El objetivo de este programa es notar la variación de las banderas después de ejecutar una operación aritmetica, en este caso suma y resta.
Espero haber documentado bien el código para que todo haya quedado claro, también quiero decir que la rutina de scanum la saque de un sitio brujo, pero podeís observar que hace emulando paso por paso.
Las variables se almacenan en el registro cx, el cual hay que moverselo a una variable, de lo contrario se pierde el valor de la variable.
El programa solo corre en un rango de -128 a 127.
Hay algunas banderas que probablemente no cambiaran.
Espero que sea de utilidad. ^w^b
imprime_car macro car
mov ah,10
mov al,car
mov bh,0
mov cx,1
int 10h
endm
print macro cad
mov ah,9
lea dx,cad
int 21h
endm
getch macro dato
mov ah,0 ; servicio 0 de Teclado
int 16h ; Interrupcion de teclado
mov dato,al
endm
cursor_xy macro X,Y
mov ah,2 ; servicio 2 de video
mov dh,Y ; coordenada de la fila
mov dl,X ; coordenada de la columna
mov bh,0
int 10h ; interrupcion de video
endm
putc macro car
mov ah,10
mov al,car
mov bh,0
mov cx,1
int 10h
endm
getint macro dato ;modificaciones de la macro getch
mov ah,0 ; servicio 0 de Teclado
int 16h ; Interrupcion de teclado
mov dato,ax ;cambiar a ax para recojer datos de 2bytes osea mayores a 127
endm
.data
error db "error",13,10,36
h1 db " ",13,10,
db " Registro de Estado Olger346",13,10,
db " Operaciones con Negativos ",13,10,
db " + Suma 11R122",13,10,
db " - Resta ",13,10,
db " ESC ",13,10,36
h2 db " Valor de A (127-128) ",13,10,36
h3 db " Valor de B (127-128) ",13,10,36
h4 db " - - - - O D I T S Z - A - P - C ",13,10,
db " ",13,10,
db " ",13,10,
db " Aritmeticos & Logicos Control ",13,10,
db " Acarreo = Direccion = ",13,10,
db " Paridad = Interrupcion = Valor ",13,10,
db " Auxiliar = Trazado = A= ",13,10,
db " Cero = B= ",13,10,
db " Signo = resultado ",13,10,
db " Desbordamiento = ",13,10,36
B db " ",36 ;variable xa impresion hexadecimal y otras
A dw ? ;1er valor a introducir
C dw ? ;segundo valor a introducir
G db ?
M dw ? ;resultado de suma o resta
I dw ? ;recoje un caracter ya sea +-
X db 40 ;variable de barrido de impresion
make_minus db ?
ten dw 10
msg db 0,25,36
K db 16
bla db " ",36
;variables de control de ciclo
U db 40
V db 40
W db 37
flag dw ? ;variable para almacenar el registro de estado
ntr db "0",36
control db 40
ecchi db 40
.stack
.code
mov ax,@data
mov ds,ax
cursor_xy 0,1
print h1
cursor_xy 26,6 ;coloca cursor en el primer ingreso del signo aritmetico
ciclo:
mov I,0
cursor_xy 26,6
print bla
cursor_xy 26,6
getint I
mov ax,I
mov B,al ;se imprime
print B
cmp I,4E2Bh ;podeis cambiar esto a 1 y funcionara con el 1 del teclado
je suma
cmp I, 4A2Dh ;igual podeis cambiar a 2
je resta
cmp I,01
je final
print error
jmp ciclo
;call SCAN_NUM ;scanea el signo aritmetico
;mov G,cx
suma:
mov cx,0 ; en cx queda un valor hay que resetearlo para que no haya basura en el valor que se vuelve a introducir nuevamente
mov A,0 ;limpiamos el valor que tenia la variable A
cursor_xy 0,7
print h2
cursor_xy 38,7 ;coloca cursor en el primer ingreso del primer valor
call SCAN_NUM ;scanea el primer valor
mov A,cx
cmp A,128
je suma
cmp A,-129
je suma
mov cx,0
mov C,0
cursor_xy 0,8
print h3
cursor_xy 38,8 ;coloca cursor en el primer ingreso del segund valor
call SCAN_NUM ;scanea el segundo valor
mov C,cx
cmp C,128
je suma
cmp C,-128
je suma
mov ax,A ; mov para sumar
add ax,C ; anade a ax lo q tiene c
mov M,ax ; mov la suma a la variable M
mov ax,M
xchg al,ah
push ax
call HEXA
cursor_xy 60,22
print B ;imprime la parte high de ax osea M
mov ax,M
push ax
call HEXA
cursor_xy 62,22
print B ;imprime 1byte de la parte low de ax osea M
cursor_xy 0,14
print h4 ;imprime esquema de flag
mov ax,A ; mov para sumar
add ax,C ; anade a ax lo q tiene c
pushf ; ax=Flag
pop ax ;pop F para almacenar las flags
cursor_xy 0,16 ;impresion de flags
mov flag,ax
jmp binario4
resta:
mov cx,0 ; en cx queda un valor hay que resetearlo para que no haya basura en el valor que se vuelve a introducir nuevamente
mov A,0 ; limpiamos el valor que habia en A
cursor_xy 0,7
print h2
cursor_xy 38,7 ;coloca cursor en el primer ingreso del primer valor
call SCAN_NUM ;scanea el primer valor
mov A,cx
cmp A,128
je resta
cmp A,-129
je resta
mov cx,0 ; en cx queda un valor hay que resetearlo para que no haya basura en el valor que se vuelve a introducir nuevamente
mov C,0 ;limpiamos el valor que queda en C
cursor_xy 0,8
print h3
cursor_xy 38,8 ;coloca cursor en el primer ingreso del segund valor
call SCAN_NUM ;scanea el segundo valor
mov C,cx
cmp C,128
je resta
cmp C,-129
je resta
mov ax,A ; mov para sumar
sub ax,C ; anade a ax lo q tiene c
mov M,ax ; mov la suma a la variable M
mov ax,M
xchg al,ah
push ax
call HEXA
cursor_xy 60,22
print B ;imprime la parte high de ax osea M
mov ax,M
push ax
call HEXA
cursor_xy 62,22
print B ;imprime 1byte de la parte low de ax osea M
cursor_xy 0,14
print h4 ;imprime esquema de flag
mov ax,A ; mov para sumar
sub ax,C ; anade a ax lo q tiene c
pushf ; ax=Flag
pop ax ;pop F para almacenar las flags
cursor_xy 0,16 ;impresion de flags
mov flag,ax
jmp binario4
binario1:
mov ax,A
;mov bx,ax
and ax,1 ;cambias esto ; Residuo de dividir entre 2
cursor_xy U,9
add al,48 ;suma para que aparezca el caracter en pantalla ascii
putc al
sub U,2 ; y esto para convertir a octal y ya
shr A,1
dec K ;sub K,1
cmp U,28 ;barrido para impresion de pantalla
jae binario1
add U,14
jmp binario2
binario2:
mov ax,C
;mov bx,ax
and ax,1 ;cambias esto ; Residuo de dividir entre 2
cursor_xy V,10
add al,48 ;suma para que aparezca el caracter en pantalla ascii
putc al
sub V,2 ; y esto para convertir a octal y ya
shr C,1
dec K ;sub K,1
cmp V,28 ;barrido para impresion de pantalla
jae binario2
add V,14
jmp binario3
binario3:
mov ax,M
;mov bx,ax
and ax,1 ;cambias esto ; Residuo de dividir entre 2
cursor_xy X,11
add al,48 ;suma para que aparezca el caracter en pantalla ascii
putc al
sub X,2 ; y esto para convertir a octal y ya
shr M,1
dec K ;sub K,1
cmp X,28 ;barrido para impresion de pantalla
jae binario3
add X,14
jmp ciclo
binario4:
mov ax,flag
;mov bx,ax
and ax,1 ;cambias esto ; Residuo de dividir entre 2
cursor_xy W,16
add al,48 ;suma para que aparezca el caracter en pantalla ascii
putc al
sub W,2 ; y esto para convertir a octal y ya
sub control,2
shr flag,1
;sub K,1
cmp ecchi,40
je acarreo
cmp control,34
je par
cmp control,30
je aux
cmp control,26
je zero
cmp control,24
je sig
cmp control,20
je inter
cmp W,18 ;barrido para impresion de pantalla
jae binario4
add W,20
add control,20
jmp binario1
par:
cursor_xy 20,19
putc al
jmp binario4
zero:
cursor_xy 20,21
putc al
jmp binario4
sig:
cursor_xy 20,22
putc al
cursor_xy 20,23
print ntr
jmp binario4
inter:
cursor_xy 40,19
putc al
cursor_xy 40,18
print ntr
cursor_xy 40,20
print ntr
jmp binario4
acarreo:
cursor_xy 20,18
putc al
sub ecchi,2
jmp binario4
aux:
cursor_xy 20,20
putc al
jmp binario4
final:
mov ah,21h
int 21h
;/////////RUTINA SCAN_NUM
; -32768 : 65535
; gets the multi-digit SIGNED number from the keyboard,
; and stores the result in CX register:
SCAN_NUM PROC NEAR
PUSH DX
PUSH AX
PUSH SI
MOV CX, 0
; reset flag:
MOV make_minus, 0
next_digit:
; get char from keyboard
; into AL:
MOV AH, 00h
INT 16h
; and print it:
MOV AH, 0Eh
INT 10h
; check for MINUS:
CMP AL, '-'
JE set_minus
; check for ENTER key:
CMP AL, 0Dh ; carriage return?
JNE not_cr
JMP stop_input
not_cr:
CMP AL, 8 ; 'BACKSPACE' pressed?
JNE backspace_checked
MOV DX, 0 ; remove last digit by
MOV AX, CX ; division:
DIV ten ; AX = DX:AX / 10 (DX-rem).
MOV CX, AX
PUTC ' ' ; clear position.
PUTC 8 ; backspace again.
JMP next_digit
backspace_checked:
; allow only digits:
CMP AL, '0'
JAE ok_AE_0
JMP remove_not_digit
ok_AE_0:
CMP AL, '9'
JBE ok_digit
remove_not_digit:
PUTC 8 ; backspace.
PUTC ' ' ; clear last entered not digit.
PUTC 8 ; backspace again.
JMP next_digit ; wait for next input.
ok_digit:
; multiply CX by 10 (first time the result is zero)
PUSH AX
MOV AX, CX
MUL ten ; DX:AX = AX*10
MOV CX, AX
POP AX
; check if the number is too big
; (result should be 16 bits)
CMP DX, 0
JNE too_big
; convert from ASCII code:
SUB AL, 30h
; add AL to CX:
MOV AH, 0
MOV DX, CX ; backup, in case the result will be too big.
ADD CX, AX
JC too_big2 ; jump if the number is too big.
JMP next_digit
set_minus:
MOV make_minus, 1
JMP next_digit
too_big2:
MOV CX, DX ; restore the backuped value before add.
MOV DX, 0 ; DX was zero before backup!
too_big:
MOV AX, CX
DIV ten ; reverse last DX:AX = AX*10, make AX = DX:AX / 10
MOV CX, AX
PUTC 8 ; backspace.
PUTC ' ' ; clear last entered digit.
PUTC 8 ; backspace again.
JMP next_digit ; wait for Enter/Backspace.
stop_input:
; check flag:
CMP make_minus, 0
JE not_minus
NEG CX
not_minus:
POP SI
POP AX
POP DX
RET
SCAN_NUM ENDP
;//////// RUTINA HEXADECIMAL
Hexa proc near
push bp
mov bp,sp
mov al,[bp+4]
shr al,4
add al,48
cmp al,58
js nible2
add al,7
nible2: mov B,al
mov al,[bp+4]
shl al,4
shr al,4
add al,48
cmp al,58
js nible1
add al,7
nible1: mov B[1],al
pop bp
ret
Hexa endp
;////////////FIN DEL PROGRAMA
.exit
Muy bueno aunque entienda muy poco, eso hace que me agrade ver el código.
es para NASM o FASM??
No tienes permitido ver los links.
Registrarse o Entrar a mi cuenta
es para NASM o FASM??
FASM no es. NASM, no lo sé.
Se ve mas como MASM :p
No tienes permitido ver los links.
Registrarse o Entrar a mi cuentaes para NASM o FASM??
Diria que nasm por el tema de que usa esa sintaxis y cosas como el mdg db