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