Учебник по ассемблеру (ASM)
 

Ассемблер в примерах - Вывод элементов массива в строку

Вопрос:
как вывести элементы массива поочередно в строке? После вывода одного элемента очищаю строку для вывода следующего. В результате после ввода (ф. 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

   Вперёд
   Содержание