Documente Academic
Documente Profesional
Documente Cultură
PrintWord PROC
;input=AX
pushxregs
xor cx, cx
xor dx, dx
mov bx, 10
PrintWord_1:
div bx
push dx
xor dx, dx
inc cx
test ax, ax
jnz PrintWord_1
PrintWord_2:
mov ah, 2
pop dx
add dl, '0'
int 21h
loop PrintWord_2
popxregs
ret
PrintWord ENDP
OBS. Instrucțiunea DIV poate genera o eroare divide overflow dacă rezultatele, câtul
de fapt, nu încape în AX (sau AL la varianta pe 8 biți). Aceasta se întâmplă dacă numărul de
împărțit este mai mare sau egal cu 655360 și se împarte la 10. Aici este imposibil să se întâmple
așa ceva deoarece cei 16 biți superiori ai DX:AX, adică DX sunt zero.
Pentru 32 biți am putea folosi instrucțiunile 386+ și regiștrii pe 32 biți (EAX, EBX etc.),
dar dacă ținem să rămânem la instrucțiuni pe 16 biți va trebui să facem o procedură specială
pentru împărțirea cu 10.
DDIV10 PROC
;input: DX:AX
;output: quotient=DX:AX, remainder=BX
push bp
mov bp, sp
sub sp, 4
mov [bp-2], ax
mov bx, 10
mov ax, dx
xor dx, dx
div bx
mov [bp-4], ax
mov ax, [bp-2]
div bx
mov bx, dx
mov dx, [bp-4]
mov sp, bp
pop bp
ret
DDIV10 ENDP
Observați două salturi în prima buclă. Primul se execută dacă AX este nonzero, al doilea
dacă DX este diferit de zero și sunt la aceeași adresă. Împreună execută salt la PrintDword_1
dacă AX sau DX sunt diferite de zero, ceea ce este același lucru cu a spune că numărul pe 32
biți din DX:AX este nonzero.
Proceduri pentru numere cu semn sunt simplu de scris dacă le avem pe cele fără semn.
Trebuie să vedem în primul rând dacă numărul este negativ - adică bitul cel mai semnificativ
este 1, și în acest caz scriem - (minus) și inversăm semnul cu instrucțiunea NEG pe 8 sau 16
biți. Pe 32 biți ne folosim de definiția complementului față de 2 și folosim 2 instrucțiuni NOT
urmate de ADD și ADC pentru a aduna 1 la rezultat. Apoi apelăm varianta fără semn.
TEMĂ. Copiați toate secvențele de cod din acest document într-un fișier LAB3.INC,
copiați acolo și procedura PrintNewline din laboratorul precedent. Scrieți un fișier LAB3.ASM
care să încludă LAB3.INC și să folosească procedurile de acolo. Fișierul LAB3.ASM ar putea să
arate așa:
model small
.stack 1024
.data
.code
include lab3.inc
start:
mov ax, @data
mov ds, ax
call PrintNewline
mov ax, 4c00h
int 21h
end start
Rularea acestuia așa cum e scris aici, cu DX:AX=80000000h ar trebui să arate 231 =
2147483648.