Suma y Resta + Flags (registro de estado) [INTEL 8086]

Iniciado por Olger346, Julio 07, 2015, 01:01:28 AM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Julio 07, 2015, 01:01:28 AM Ultima modificación: Enero 06, 2018, 05:53:42 PM por Olger346
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
Código: asm

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
"Cuando se nace pobre, estudiar es el mayor acto de rebeldía contra el sistema. El saber rompe las cadenas de la esclavitud" -Tomas Bulat.

Muy bueno aunque entienda muy poco, eso hace que me agrade ver el código.



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
El conocimiento es libre...
La información no lo es xD

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