Консультация № 154581
16.12.2008, 14:34
0.00 руб.
0 2 2
Здравствуйте, недавно начали изучать асемблер, дали задание написать прогу: Из массива А(10) образовать масив Б(5) таким образом: b1=a1*a10. b2=a2*a9,..... b5=a5*a6, помогите пожалуйста в написании данной проги

.mode tiny
.data
a db 0,1,2,3,4,5,6,7,8,9
b dw 5 dup (?)

.code
.startup
mov si, offset a ; адрес первого байта массива А
mov bx, offset a+9 ; адрес последнего байта массива А
mov di, offset b ; адрес массива Б
mov cx, 5 ; должны сформировать 5 элементов Б
fLoop: ; начало цикла
lodsb ; al = [si], si = si+1
mul byte ptr [bx] ; ax = al * [bx]
dec bx ; подготовим адресацию для следующего шага
stosw ; [di] = ax, di = di+2
loop fLoop ; зациклим
mov ax,4c00h
int 21h
end

Уважаемые эксперты. данную прогу нужно скомпилировать с расширением .exe c помощью компилятора TASM и TLINK, в проге должен быть вывод на экран первоначального массива и полученного. моих знаний не хватает чтобы переделать данный вариант программы под мои требования. помогите плиз довести данную прогу до нужного варианта

Обсуждение

давно
Старший Модератор
31795
6196
16.12.2008, 15:22
общий
это ответ
Здравствуйте, Volk1290!

Переделанная программа в приложениии, проверялась TASM 2.0
Вопросы задавайте в мини-форуме.
Удачи!

Приложение:
model small

.data
a db 0,1,2,3,4,5,6,7,8,9
b dw 5 dup (?)
.stack 100

.code
begin:
mov ax,@data
mov ds,ax
mov es,ax
;выводим исходный массив
mov si,offset a
mov cx,10
;читаем байт
isOne: lodsb
;сбрасываем сташий байт в слове
xor ah,ah
;выводим слово
call OutNumber
loop isOne
;
mov si, offset a ; адрес первого байта массива А
mov bx, offset a+9 ; адрес последнего байта массива А
mov di, offset b ; адрес массива Б
mov cx, 5 ; должны сформировать 5 элементов Б
fLoop: ; начало цикла
lodsb ; al = [si], si = si+1
mul byte ptr [bx] ; ax = al * [bx]
dec bx ; подготовим адресацию для следующего шага
stosw ; [di] = ax, di = di+2
loop fLoop ; зациклим
;переходим на новую строку
mov al,13
int 29h
mov al,10
int 29h
;выводим полученный массив
mov si,offset b
mov cx,5
;читаем слово
isTwo: lodsw
;выводим слово
call outNumber
loop isTwo
;любая клавиша
xor ax,ax
int 16h
mov ax,4c00h
int 21h
;сохраняем парамерт цикла вывода
outNumber: push cx
xor cx,cx
;будем выводить в десятичной системе
mov bx,10
;получаем остаток от деления на 10
isDiv: xor dx,dx
div bx
;запоминаем его в стеке
push dx
;считаем количество запомненых цифр
inc cx
;пока не достигнем нуля
or ax,ax
jnz isDiv
;вывод происходит в нужном порядке
isOut: pop ax
;преобразовываем число в символ
or al,30h
;выводим
int 29h
;пока не выведем все запомненые числа из стека
loop isout
;выводим разделительный пробел
mov al,' '
int 29h
;востанавливаем параметр внешнего цикла
pop cx
ret
end begin
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
18.12.2008, 15:20
общий
это ответ
Здравствуйте, Volk1290!
Предлагаю 2 варианта реализации программы. 1Вариант, как было изначально в листинге для односегментной программы (*.com), 2 вариант много сегментный (*.exe). Пояснения в приложении.

Приложение:
; 1вариант
.model tiny
.data
a db 219,1,92,99,0,15,186,70,18,249
b dw 5 dup (?)

stk db 0dh,0ah ;строка вывода (формат десятичный)
db 'Array a => '
a_d db 39 dup(20h),0dh,0ah ;массива a
db 'Array b => '
b_d db 29 dup(20h),0dh,0ah,'$' ;массива b

.code
.startup
mov si, offset a ; адрес первого байта массива А
mov bx, offset a+9 ; адрес последнего байта массива А
mov di, offset b ; адрес массива Б
mov cx, 5 ; должны сформировать 5 элементов Б

fLoop: ; начало цикла
lodsb ; al = [si], si = si+1
mul byte ptr [bx] ; ax = al * [bx]
dec bx ; подготовим адресацию для следующего шага
stosw ; [di] = ax, di = di+2
loop fLoop ; зациклим
;-------------------------------Добавил---
call ascii_ad ;процедура для массива a
call ascii_bd ;процедура для массива b

mov ah,09h ;Вывод результата на экран
mov dx,offset stk
int 21h
;-----------------------------------------
mov ax,4c00h
int 21h

;---------Процедуры-----
;Процедура перевода в десятичный формат
;массива b
;Процедура аналогична с процедурой ascii_ad
;Отличие в том, что проверка ведется по следующим
;диапазонам чисел
;от 0 - 9, от 10 - 99, от 100 - 999, от 1000 - 9999
;Используются при делении регистры ax, bx и dx
;остаток от деления ax на bx будет в регистре dx
ascii_bd:
mov cx,5
mov si,offset b
mov di,offset b_d
mov bx,0ah

abd00:
lodsw
cmp ax,09h
ja abd30
jmp short abd35

abd30:
cmp ax,63h
ja abd31
inc di
jmp short abd35

abd31:
cmp ax,03e7h
ja abd32
add di,2
jmp short abd35

abd32:
cmp ax,270fh
ja abd33
add di,3
jmp short abd35

abd33:
add di,4

abd35:
push di

adb01:
cmp ax,0ah
jb adb03
xor dx,dx
div bx
or dl,30h
mov [di],dl
dec di
jmp short adb01

adb03:
or al,30h
mov [di],al
pop di
inc di
inc di

abd_20:
loop abd00

ret
;-----------------------
;Процедура вывода на экран массива a
;Производится проверка каждого байта массива для определения
;количество байтов ascii-кода
;Проверка от 0 - 9(десятичное), от 10 - 99(десятичное)
;По результату проверки отводится 1 байт, 2 байта или 3 байта
ascii_ad:
xor ax,ax ;очистка регистра ax
mov cx,0ah ;счетчик для цикла
mov si,offset a ;адрес массива a
mov di,offset a_d ;адрес массива вывода
mov bl,0ah ;фактор деления

asc00:
lodsb ;загрузка байта в al
cmp al,09h ;Проверка на диапазон от 0 - 9(десятичное)
ja asc01
jmp short asc20

asc01:
cmp al,63h ;Проверка на диапазон от 10 - 99(десятичное)
ja asc02
inc di ;от 10 - 99 необходимо 2 байта для ascii-кода
jmp short asc20

asc02:
add di,2 ;если число больше 99(десятичное), понадобится 3 байта для ascii-кода

asc20:
push di ;сохраним позицию указателя
asc21:
cmp al,0ah ;если в al число меньше 10(десятичное), то на метку asc22
jb asc22
xor ah,ah ;иначе обнуляем ah
div bl ;делим al на bl
or ah,30h ;к остатку прибавим 30h
mov [di],ah ;запишем цифру
dec di ;уменьшаем адрес
jmp short asc21 ;и на метку asc21

asc22:
or al,30h ;если в al от 0 - 9, переведем число в ascii-символ
mov [di],al ;запишем
pop di ;восстановим указатель адреса
inc di
inc di ;сделаем разделитель
loop asc00 ;и продолжаем цикл
ret

end

;2вариант
data segment
a db 219,1,92,99,0,15,186,70,18,249
b dw 5 dup (?)

stk db 0dh,0ah ;строка вывода (формат десятичный)
db 'Array a => '
a_d db 39 dup(20h),0dh,0ah ;массива a
db 'Array b => '
b_d db 29 dup(20h),0dh,0ah,'$' ;массива b
data ends
stacksg segment stack
dw 50h dup(?)
stacksg ends
code segment
assume cs:code,ds:data
begin:
mov ax,data
mov ds,ax
mov es,ax

mov si, offset a ; адрес первого байта массива А
mov bx, offset a+9 ; адрес последнего байта массива А
mov di, offset b ; адрес массива Б
mov cx, 5 ; должны сформировать 5 элементов Б

fLoop: ; начало цикла
lodsb ; al = [si], si = si+1
mul byte ptr [bx] ; ax = al * [bx]
dec bx ; подготовим адресацию для следующего шага
stosw ; [di] = ax, di = di+2
loop fLoop ; зациклим
;-------------------------------Добавил---
call ascii_ad ;процедура для массива a
call ascii_bd ;процедура для массива b

mov ah,09h ;Вывод результата на экран
mov dx,offset stk
int 21h
;-----------------------------------------
mov ax,4c00h
int 21h

;---------Процедуры-----
;Процедура перевода в десятичный формат
;массива b
;Процедура аналогична с процедурой ascii_ad
;Отличие в том, что проверка ведется по следующим
;диапазонам чисел
;от 0 - 9, от 10 - 99, от 100 - 999, от 1000 - 9999
;Используются при делении регистры ax, bx и dx
;остаток от деления ax на bx будет в регистре dx
ascii_bd:
mov cx,5
mov si,offset b
mov di,offset b_d
mov bx,0ah

abd00:
lodsw
cmp ax,09h
ja abd30
jmp short abd35

abd30:
cmp ax,63h
ja abd31
inc di
jmp short abd35

abd31:
cmp ax,03e7h
ja abd32
add di,2
jmp short abd35

abd32:
cmp ax,270fh
ja abd33
add di,3
jmp short abd35

abd33:
add di,4

abd35:
push di

adb01:
cmp ax,0ah
jb adb03
xor dx,dx
div bx
or dl,30h
mov [di],dl
dec di
jmp short adb01

adb03:
or al,30h
mov [di],al
pop di
inc di
inc di

abd_20:
loop abd00

ret
;-----------------------
;Процедура вывода на экран массива a
;Производится проверка каждого байта массива для определения
;количество байтов ascii-кода
;Проверка от 0 - 9(десятичное), от 10 - 99(десятичное)
;По результату проверки отводится 1 байт, 2 байта или 3 байта
ascii_ad:
xor ax,ax ;очистка регистра ax
mov cx,0ah ;счетчик для цикла
mov si,offset a ;адрес массива a
mov di,offset a_d ;адрес массива вывода
mov bl,0ah ;фактор деления

asc00:
lodsb ;загрузка байта в al
cmp al,09h ;Проверка на диапазон от 0 - 9(десятичное)
ja asc01
jmp short asc20

asc01:
cmp al,63h ;Проверка на диапазон от 10 - 99(десятичное)
ja asc02
inc di ;от 10 - 99 необходимо 2 байта для ascii-кода
jmp short asc20

asc02:
add di,2 ;если число больше 99(десятичное), понадобится 3 байта для ascii-кода

asc20:
push di ;сохраним позицию указателя
asc21:
cmp al,0ah ;если в al число меньше 10(десятичное), то на метку asc22
jb asc22
xor ah,ah ;иначе обнуляем ah
div bl ;делим al на bl
or ah,30h ;к остатку прибавим 30h
mov [di],ah ;запишем цифру
dec di ;уменьшаем адрес
jmp short asc21 ;и на метку asc21

asc22:
or al,30h ;если в al от 0 - 9, переведем число в ascii-символ
mov [di],al ;запишем
pop di ;восстановим указатель адреса
inc di
inc di ;сделаем разделитель
loop asc00 ;и продолжаем цикл
ret
code ends
end begin
Форма ответа