Created
October 28, 2023 22:32
-
-
Save ManuelWiki/fddd9e0581f2dac0db874ae9f5dd1805 to your computer and use it in GitHub Desktop.
Programa que divide una palabra doble entre una palabra usando el algoritmo de restas consecutivas en Turbo Assembler (MASM/TASM)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; TITULO: Programa que divide una palabra doble entre una palabra usando el algoritmo de restas consecutivas | |
ideal | |
dosseg | |
model small | |
stack 256 | |
dataseg | |
codsal db 0 | |
; Mis variables { | |
dvdndo dd 515 | |
dvsor dw 4 | |
cocien dw 0 | |
resduo dw 0 | |
;} | |
codeseg | |
proc PrintDecimal | |
push ax | |
push bx | |
push cx | |
push dx | |
; check if negative | |
test ax,08000h | |
jz PositiveAx | |
; put '-' on the screen | |
push ax | |
mov dl,'-' | |
mov ah,2 | |
int 21h | |
pop ax | |
neg ax ; make it positive | |
PositiveAx: | |
mov cx,0 ; will count how many time we did push | |
mov bx,10 ; the divider | |
put_mode_to_stack: | |
xor dx,dx | |
div bx | |
add dl,30h | |
; dl is the current LSB digit | |
; we cant push only dl so we push all dx | |
push dx | |
inc cx | |
cmp ax,9 ; check if it is the last time to div | |
jg put_mode_to_stack | |
cmp ax,0 | |
jz pop_next ; jump if ax was totally 0 | |
add al,30h | |
mov dl, al | |
mov ah, 2h | |
int 21h ; show first digit MSB | |
pop_next: | |
pop ax ; remove all rest LIFO (reverse) (MSB to LSB) | |
mov dl, al | |
mov ah, 2h | |
int 21h ; show all rest digits | |
loop pop_next | |
pop dx | |
pop cx | |
pop bx | |
pop ax | |
ret | |
endp PrintDecimal | |
proc PrintNewLine | |
push dx | |
mov dx, 0Ah | |
call PrintChar | |
pop dx | |
ret | |
endp PrintNewLine | |
proc PrintChar | |
push ax | |
mov ah, 02h | |
int 21h | |
pop ax | |
ret | |
endp PrintChar | |
inicio: | |
mov ax, @data | |
mov ds, ax | |
; ###### MI CODIGO ####### { | |
; copiamos el dividendo (la doble palabra a dx:ax) | |
mov dx, [word dvdndo + 2] | |
mov ax, [word dvdndo] | |
; Como usaremos 'cx', lo limpiamos antes | |
mov cx, 0 | |
; Haremos un ciclo en el que se va a restar 'dvsor' a el dividendo (dx:ax) hasta que no se pueda | |
; Esto es porque, por ejemplo, al 50, le puedes restar 7 7 veces porque cabe el 7 cabe 7 veces en el 50 | |
; Otro ejemplo: al 80, le puedes restar 2 40 veces porque el 2 cabe 40 veces en el 80 | |
; O sea que nuestro ciclo solo va a contar cuantas veces podemos restarle un numero (el dvsor) a otro (el dvdndo) | |
mientras: | |
; Primero vemos si podemos restar el 'dvsor' al dividendo | |
; Lo haremos viendo si 'dvsor' es mayor al dividendo (dx:ax) | |
; Como el dividendo es 2 palabras, tenemos que hacerlo en 2 pasos | |
cmp dx, 0 | |
jne se_puede ; Si 'dx' es 0, entonces el dividendo es mayor asi que si se puede | |
jmp otra_cmp ; Si no, hay que hacer otra comparacion | |
otra_cmp: | |
cmp ax, [dvsor] | |
jae se_puede ; Si ax es mayor que 'dvsor', el dividendo es mayor, asi que si podemos restar | |
jmp fin_mientras ; Pero si no, no se puede asi que hay que terminar el ciclo | |
se_puede: | |
; Para restar una palabra a una doble palabra tenemos que hacerlo en 2 pasos | |
; Primero restamos la palabra a la parte baja de la doble palabra | |
sub ax, [dvsor] | |
; Luego, restamos, con sbb, 0 a la parte alta. Esto es por si hubo un prestamo pendiente | |
sbb dx, 0 | |
; Cada vez que restemos, vamos a sumarle 1 a 'cx' para llevar la cuenta | |
inc cx | |
jmp mientras | |
fin_mientras: | |
; Ya que termina el ciclo, el residuo queda guardado en dx:ax, y el cociente en 'cx' | |
mov [cocien], cx | |
mov [resduo], ax | |
; } | |
mov ax, [cocien] | |
call PrintDecimal | |
call PrintNewLine | |
mov ax, [resduo] | |
call PrintDecimal | |
salir: | |
mov ah, 04Ch | |
mov al, [codsal] | |
int 21h | |
end inicio |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment