 |
Ассемблер в примерах - Вывод элементов массива в строку
- Вопрос:
-
как вывести элементы массива поочередно в строке? После вывода одного элемента очищаю строку для вывода следующего. В результате после ввода (ф. vvod закомментировал) или инициализации massiv dw 123,56,1,0,89,104 получаю
123
563
1 3
0 3
893
104
Код com-проги в приложении:
.386
cseg segment use16
assume cs:cseg
org 100h
main:
;mov ah,09h
;mov dx,offset PriglKVvodu
;int 21h
;call perevodkursora
mov bp,offset string
;mov si,0
;vvodmassiva:
;call vvod
;mov massiv[si],ax
;add si,2 ;к следующему элементу
;call perevodkursora
;dec schetchik
;jnz vvodmassiva
;;call rasshir_vdopkod
;call perevodkursora
mov schetchik,6
mov si,offset massiv
vivodmassiva:
mov bp,offset string
mov ax,[si]
call vivod
add si,2
mov ah,09h
mov dx,offset string
int 21h
mov schetchikstroki,7
ochistkastroki:
mov di,offset string
mov word ptr[di],20h
inc di
dec schetchikstroki
jnz ochistkastroki
call perevodkursora
dec schetchik
jnz vivodmassiva
mov ax,4c00h ;стандартный выход для EXE-проги работает и в COM-проге
int 21h
;ещё один вариант очистки строки вывода
;ochistkastroki proc
;mov di,offset string
;cld
;mov ax,20h ;в отладчике это число подстявлялось вместо элемента массива в ф. vivod
;mov cx,7
;rep stosw
;ret
;ochistkastroki endp
vivod proc
xor cx,cx
xor bx,bx
mov bl,10
.divide:
xor dx,dx
div bx
add dx,'0'
push dx
inc cx
or ax,ax
jnz .divide
.reverse:
pop ax
;stosb
mov [bp],al
inc bp
loop .reverse
ret
vivod endp
perevodkursora proc
lea dx,ent
mov ah,09h
int 21h
ret
perevodkursora endp
vvod proc
xor ax,ax
mov di,0
mov znak,0
myinput:
mov ah,08h ;ввожу и показываю знак числа
int 21h
cmp al,13
je done
cmp al,'+'
jz znakvpamyat
cmp al,'-'
jz znakvpamyat
cmp znak,0
jz null
jmp inpt
null:
cmp al,30h
jnz myinput
;mov si,30h
call vivodsimvola
mov ax,0
mov znak,'+'
jmp vihod
inpt:
cmp al,39h
ja myinput
cmp al,30h
jb myinput
cmp al,30h
jnz b
cmp di,0
jz myinput
;нет
b:
call vivodsimvola
sub al,30h;’0’
xor ah,ah
mov cx,ax
mov ax,di
mov bx,10
mul bx
add ax,cx
mov di,ax
jmp myinput
znakvpamyat:
cmp znak,0
jnz myinput
mov znak,al
call vivodsimvola
jmp myinput
done: mov ax,di
cmp znak,'+'
jnz otritsatel
cmp ax,[VerhGranDiapaz]
jbe vihod
call perevodkursora
call vihodzadiapazon
mov di,0
mov znak,0
jmp myinput
otritsatel:
cmp ax,[NizhGranDiapaz]
jbe vihod
call perevodkursora
call vihodzadiapazon
mov di,0
mov znak,0
jmp myinput
vihod:
ret
vvod endp
vivodsimvola proc
mov ah,02h
mov dl,al
int 21h
ret
vivodsimvola endp
vihodzadiapazon proc
mov ah,09h
mov dx,offset zadiapazon
int 21h
ret
vihodzadiapazon endp
rasshir_vdopkod proc
cmp znak,'+' ;+А?
jz polozhitel ;да
neg ax
polozhitel:
ret
rasshir_vdopkod endp
string db 7 dup(20h),'$'
massiv dw 123,56,1,0,89,104
i dw 0
ent db 13,10,'$' ;перевод курсора на строку ниже
schetchik db 6
zadiapazon db 'The entered number is not included into range of numbers with a sign, enter number again: $'
NizhGranDiapaz dw 128
VerhGranDiapaz dw 127
PerSlag dw 0
PriglKVvodu db 'Enter a sign, number and press Enter:$'
znak db 0 ;вместо регистра si в vvod
schetchikstroki db 7
cseg ends
end main
- Ответ:
-
1)
mov schetchikstroki,7
mov di,offset string
ochistkastroki:
mov byte ptr[di],20h
inc di
dec schetchikstroki
jnz ochistkastroki
сравнив со своим кодом разберётесь
2)
Данный цикл в Вашей программе лишний:
ochistkastroki:
. . .
jnz ochistkastroki
т.к. получается Вы два раза заполняете свою строку, первый раз когда записываете цифры числа, второй когда записываете пробел. Зачем? Вам достаточно только добавить команду:
Код:
loop .reverse
mov byte ptr[bp],'$';записываем маркер конца строки
ret
Тем самым Вы записываете после своего сформированого числа, маркер конца строки для функции 09h прерывания 21h.
Ещё как совет, можно иначе записать саму строку вывода:
ent db 13,10
string db 7 dup(20h),'$'
Формируете число как в программе с метки string , а вот выводите начиная с метки ent . Таким образом можно выбросить ещё код п/п perevodkursora
|  |