Saltar al contenido
Underc0de /foro

Addition and Subtraction + Flags (status register) [INTEL 8086]

🌐 This is an automatic translation of a topic from Underc0de, the largest Spanish-speaking hacking and IT community. Read the original (Spanish) and reply →
Olger346 ·
The goal of this program is to observe how the flags change after executing an arithmetic operation, in this case addition and subtraction.<br />I hope I documented the code well enough so that everything is clear. I also want to mention that I took the scanum routine from a wizard's site, but you can see what it does by emulating it step by step.<br /><br />The variables are stored in the cx register, which has to be moved into a variable, otherwise the variable's value is lost.<br />The program only works in a range from -128 to 127. <br />Some flags will probably not change.<br /><br />I hope it's useful. ^w^b
Código: asm
<br />imprime_car macro   car<br />    <br />    mov    ah,10<br />    mov    al,car<br />    mov    bh,0<br />    mov    cx,1<br />    int    10h      <br /><br />endm<br /><br />print  macro cad<br />    mov   ah,9<br />    lea   dx,cad<br />    int   21h<br />    <br />endm    <br /><br />getch macro dato<br />    <br />    mov  ah,0   ; servicio 0 de Teclado<br />    int  16h    ; Interrupcion de teclado<br />    <br />    mov  dato,al<br />    <br />endm <br /><br />cursor_xy  macro X,Y<br />    <br />    mov    ah,2     ; servicio 2 de video<br />    mov    dh,Y     ; coordenada de la fila<br />    mov    dl,X     ; coordenada de la columna<br />    mov    bh,0     <br />    int    10h      ; interrupcion de video<br />    <br />endm<br /><br />putc macro   car<br />    <br />    mov    ah,10<br />    mov    al,car<br />    mov    bh,0<br />    mov    cx,1<br />    int    10h<br />endm  <br /><br />getint macro dato       ;modificaciones de la macro getch<br />    <br />    mov  ah,0   ; servicio 0 de Teclado<br />    int  16h    ; Interrupcion de teclado<br />    <br />    mov  dato,ax ;cambiar a ax para recojer datos de 2bytes osea mayores a 127<br />    <br />endm <br /><br />.data<br />  error db "error",13,10,36<br />  h1 db "                                                      ",13,10,<br />     db "                  Registro de Estado          Olger346",13,10,<br />     db "              Operaciones con Negativos               ",13,10,<br />     db "                      + Suma                    11R122",13,10,<br />     db "                      - Resta                         ",13,10,<br />     db "                      ESC                             ",13,10,36<br />          <br />  h2 db "                 Valor de A (127-128)                 ",13,10,36 <br />  h3 db "                 Valor de B (127-128)                 ",13,10,36<br />     <br />  h4 db "       - - - - O D I T S Z - A - P - C                ",13,10,<br />     db "                                                      ",13,10,<br />     db "                                                      ",13,10, <br />     db " Aritmeticos & Logicos   Control                      ",13,10,<br />     db " Acarreo         =       Direccion    =                    ",13,10,<br />     db " Paridad         =       Interrupcion =           Valor    ",13,10,<br />     db " Auxiliar        =       Trazado      =           A=       ",13,10,<br />     db " Cero            =                                B=       ",13,10,<br />     db " Signo           =                         resultado       ",13,10,<br />     db " Desbordamiento  =                                         ",13,10,36<br />                                                                     <br />   B db "  ",36 ;variable xa impresion hexadecimal y otras<br />   A dw ?       ;1er valor a introducir<br />   C dw ?       ;segundo valor a introducir<br />   G db ?   <br />   M dw ?       ;resultado de suma o resta<br />   I dw ?       ;recoje un caracter ya sea +-<br />   X db 40  ;variable de barrido de impresion <br />                                                    make_minus db ?<br /> ten dw 10<br /> msg db    0,25,36 <br /> K   db 16<br /> bla db "   ",36 <br />             ;variables de control de ciclo<br /> U   db 40<br /> V   db 40<br /> W   db 37<br />flag dw ?      ;variable para almacenar el registro de estado<br /> ntr db "0",36  <br /> control db 40   <br /> ecchi db 40<br /><br />   <br />.stack<br />   <br />.code<br />       <br />    mov ax,@data<br />    mov ds,ax  <br />       <br />    cursor_xy 0,1      <br />    print h1        <br />    cursor_xy 26,6  ;coloca cursor en el primer ingreso del signo aritmetico<br />    <br />    <br />ciclo:    <br />    <br />    mov I,0<br />    cursor_xy 26,6 <br />    print bla<br />    cursor_xy 26,6 <br />    getint  I <br />    mov ax,I<br />    mov B,al ;se imprime  <br />    print B    <br />    <br />    cmp I,4E2Bh    ;podeis cambiar esto a 1 y funcionara con el 1 del teclado<br />    je  suma<br />    <br />    cmp I, 4A2Dh   ;igual podeis cambiar a 2<br />    je  resta <br />    <br />    cmp I,01<br />    je  final<br />    <br />    print error<br />    jmp ciclo <br />    <br />    ;call SCAN_NUM   ;scanea el signo aritmetico     <br />    ;mov     G,cx       <br />    <br />    <br />suma:<br />     <br />    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<br />    mov A,0         ;limpiamos el valor que tenia la variable A<br />    cursor_xy 0,7  <br />    print h2<br />    cursor_xy 38,7  ;coloca cursor en el primer ingreso del primer valor<br />    call SCAN_NUM   ;scanea el primer valor<br />    mov     A,cx    <br />    <br />    cmp   A,128<br />    je    suma<br />    <br />    cmp   A,-129<br />    je    suma<br />    <br />    mov cx,0<br />    mov C,0<br />    cursor_xy 0,8<br />    print h3<br />    cursor_xy 38,8  ;coloca cursor en el primer ingreso del segund valor<br />    call SCAN_NUM   ;scanea el segundo valor<br />    mov     C,cx     <br />    <br />    cmp   C,128<br />    je   suma<br />    <br />    cmp   C,-128<br />    je    suma<br />    <br />    mov  ax,A ; mov para sumar<br />    add  ax,C ; anade a ax lo q tiene c<br />    mov  M,ax ; mov la suma a la variable M<br />    <br />    mov ax,M<br />    xchg al,ah<br />    push ax<br />    call HEXA<br />        <br />    cursor_xy 60,22    <br />    print B   ;imprime la parte high de ax osea M<br />    <br />    mov  ax,M<br />    push ax<br />    call HEXA<br />    <br />    <br />    cursor_xy 62,22<br />    print B ;imprime 1byte de la parte low de ax osea M<br />    <br />    cursor_xy 0,14<br />    print h4 ;imprime esquema de flag<br />    <br />    <br />    mov  ax,A ; mov para sumar<br />    add  ax,C ; anade a ax lo q tiene c<br />        <br />    pushf    ; ax=Flag<br />    pop ax ;pop F para almacenar las flags <br />    <br />    cursor_xy 0,16  ;impresion de flags<br />    mov flag,ax<br />                             <br />    jmp binario4<br />        <br />    <br />    <br />    <br />resta:   <br />   <br />    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<br />    mov A,0         ; limpiamos el valor que habia en A<br />    cursor_xy 0,7  <br />    print h2<br />    cursor_xy 38,7  ;coloca cursor en el primer ingreso del primer valor<br />    call SCAN_NUM   ;scanea el primer valor<br />    mov     A,cx  <br />    <br />    cmp   A,128<br />    je   resta<br />    <br />    cmp   A,-129<br />    je    resta<br />    <br />    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<br />    mov C,0         ;limpiamos el valor que queda en C<br />    cursor_xy 0,8<br />    print h3<br />    cursor_xy 38,8  ;coloca cursor en el primer ingreso del segund valor<br />    call SCAN_NUM   ;scanea el segundo valor<br />    mov     C,cx<br />    <br />    cmp   C,128<br />    je   resta<br />    <br />    cmp   C,-129<br />    je    resta  <br />    <br />    <br />    mov  ax,A       ; mov para sumar<br />    sub  ax,C       ; anade a ax lo q tiene c<br />    mov  M,ax       ; mov la suma a la variable M<br />    <br />    mov ax,M<br />    xchg al,ah<br />    push ax<br />    call HEXA<br />    cursor_xy 60,22<br />    print B         ;imprime la parte high de ax osea M<br />    <br />    mov ax,M<br />    push ax<br />    call HEXA<br />    cursor_xy 62,22<br />    print B         ;imprime 1byte de la parte low de ax osea M<br />    <br />    <br />    <br />    cursor_xy 0,14<br />    print h4        ;imprime esquema de flag <br />    <br />    mov  ax,A ; mov para sumar<br />    sub  ax,C ; anade a ax lo q tiene c<br />        <br />    pushf    ; ax=Flag<br />    pop ax ;pop F para almacenar las flags <br />    <br />    cursor_xy 0,16  ;impresion de flags<br />    mov flag,ax<br />                                       <br />    jmp binario4<br />        <br />   <br /><br />binario1:<br />        <br />        mov   ax,A   <br />                            ;mov   bx,ax<br />        and   ax,1          ;cambias esto            ; Residuo de dividir entre 2   <br />        <br />        <br />        cursor_xy U,9 <br />        add   al,48     ;suma para que aparezca el caracter en pantalla ascii <br />        putc  al<br />       <br />        sub   U,2       ; y esto para convertir a octal y ya<br />        shr   A,1 <br />        dec   K                ;sub K,1 <br />         <br />        cmp U,28        ;barrido para impresion de pantalla<br />        jae binario1<br />        add U,14<br />        <br />        jmp binario2<br />        <br />binario2:<br /><br />        mov   ax,C   <br />                            ;mov   bx,ax<br />        and   ax,1          ;cambias esto            ; Residuo de dividir entre 2   <br />        <br />        <br />        cursor_xy V,10 <br />        add   al,48    ;suma para que aparezca el caracter en pantalla ascii <br />        putc  al<br />       <br />        sub   V,2  ; y esto para convertir a octal y ya<br />        shr   C,1 <br />        dec   K                ;sub K,1 <br />         <br />        cmp V,28      ;barrido para impresion de pantalla<br />        jae binario2<br />        add V,14<br />        jmp binario3   <br />        <br />binario3:<br /> <br />         <br />        mov   ax,M   <br />                                  ;mov   bx,ax<br />        and   ax,1          ;cambias esto            ; Residuo de dividir entre 2   <br />        <br />        <br />        cursor_xy X,11<br />        add   al,48    ;suma para que aparezca el caracter en pantalla ascii <br />        putc  al<br />       <br />        sub   X,2  ; y esto para convertir a octal y ya<br />        shr   M,1 <br />        dec   K                ;sub K,1 <br />         <br />        cmp X,28      ;barrido para impresion de pantalla<br />        jae binario3<br />        add X,14  <br />        jmp ciclo<br /><br />binario4:<br /> <br />         <br />        mov   ax,flag   <br />                                  ;mov   bx,ax<br />        and   ax,1          ;cambias esto            ; Residuo de dividir entre 2   <br />        <br />        <br />        cursor_xy W,16<br />        add   al,48    ;suma para que aparezca el caracter en pantalla ascii <br />        putc  al<br />       <br />        sub   W,2  ; y esto para convertir a octal y ya<br />        sub   control,2<br />        shr   flag,1 <br />                       ;sub K,1 <br />        <br />        cmp   ecchi,40<br />        je    acarreo<br />        cmp   control,34 <br />        je    par <br />        cmp   control,30<br />        je    aux<br />        cmp   control,26<br />        je    zero<br />        cmp   control,24<br />        je    sig<br />        cmp   control,20<br />        je    inter <br />        <br />        <br />         <br />        cmp W,18      ;barrido para impresion de pantalla<br />        jae binario4<br />        add W,20<br />        add control,20<br />        jmp binario1 <br />        <br />        <br />par:<br />        cursor_xy     20,19<br />        putc al<br />        jmp binario4  <br /><br />zero:<br />        cursor_xy     20,21<br />        putc al<br />        jmp binario4<br />sig:<br />        cursor_xy     20,22<br />        putc al<br />        cursor_xy     20,23<br />        print ntr<br />        jmp binario4<br />inter:  <br />        cursor_xy     40,19<br />        putc al <br />        cursor_xy     40,18<br />        print ntr<br />        cursor_xy     40,20<br />        print ntr<br />        jmp binario4<br /><br />acarreo: <br />        <br />        cursor_xy     20,18<br />        putc al<br />        sub ecchi,2<br />        jmp binario4<br />aux:<br />        cursor_xy     20,20<br />        putc al<br />        jmp binario4        <br />        <br />                          <br />final:<br />    mov ah,21h<br />    int 21h<br />              <br />              <br />              <br />              <br />              <br />              <br />              <br />              <br />              <br />              <br />              <br />              <br />              <br />              <br />              <br />        <br />      <br />;/////////RUTINA SCAN_NUM<br />    <br />; -32768 : 65535<br />; gets the multi-digit SIGNED number from the keyboard,<br />; and stores the result in CX register:<br />SCAN_NUM        PROC    NEAR<br />        PUSH    DX<br />        PUSH    AX<br />        PUSH    SI<br />        <br />        MOV     CX, 0<br /><br />        ; reset flag:<br />        MOV     make_minus, 0<br /><br />next_digit:<br /><br />        ; get char from keyboard<br />        ; into AL:<br />        MOV     AH, 00h<br />        INT     16h<br />        ; and print it:<br />        MOV     AH, 0Eh<br />        INT     10h<br /><br />        ; check for MINUS:<br />        CMP     AL, '-'<br />        JE      set_minus<br /><br />        ; check for ENTER key:<br />        CMP     AL, 0Dh  ; carriage return?<br />        JNE     not_cr<br />        JMP     stop_input<br />not_cr:<br /><br /><br />        CMP     AL, 8                   ; 'BACKSPACE' pressed?<br />        JNE     backspace_checked<br />        MOV     DX, 0                   ; remove last digit by<br />        MOV     AX, CX                  ; division:<br />        DIV     ten                  ; AX = DX:AX / 10 (DX-rem).<br />        MOV     CX, AX<br />        PUTC    ' '                     ; clear position.<br />        PUTC    8                       ; backspace again.<br />        JMP     next_digit<br />backspace_checked:<br /><br /><br />        ; allow only digits:<br />        CMP     AL, '0'<br />        JAE     ok_AE_0<br />        JMP     remove_not_digit<br />ok_AE_0:        <br />        CMP     AL, '9'<br />        JBE     ok_digit<br />remove_not_digit:       <br />        PUTC    8       ; backspace.<br />        PUTC    ' '     ; clear last entered not digit.<br />        PUTC    8       ; backspace again.        <br />        JMP     next_digit ; wait for next input.       <br />ok_digit:<br /><br /><br />        ; multiply CX by 10 (first time the result is zero)<br />        PUSH    AX<br />        MOV     AX, CX<br />        MUL     ten                  ; DX:AX = AX*10<br />        MOV     CX, AX<br />        POP     AX<br /><br />        ; check if the number is too big<br />        ; (result should be 16 bits)<br />        CMP     DX, 0<br />        JNE     too_big<br /><br />        ; convert from ASCII code:<br />        SUB     AL, 30h<br /><br />        ; add AL to CX:<br />        MOV     AH, 0<br />        MOV     DX, CX      ; backup, in case the result will be too big.<br />        ADD     CX, AX<br />        JC      too_big2    ; jump if the number is too big.<br /><br />        JMP     next_digit<br /><br />set_minus:<br />        MOV     make_minus, 1<br />        JMP     next_digit<br /><br />too_big2:<br />        MOV     CX, DX      ; restore the backuped value before add.<br />        MOV     DX, 0       ; DX was zero before backup!<br />too_big:<br />        MOV     AX, CX<br />        DIV     ten  ; reverse last DX:AX = AX*10, make AX = DX:AX / 10<br />        MOV     CX, AX<br />        PUTC    8       ; backspace.<br />        PUTC    ' '     ; clear last entered digit.<br />        PUTC    8       ; backspace again.        <br />        JMP     next_digit ; wait for Enter/Backspace.<br />        <br />        <br />stop_input:<br />        ; check flag:<br />        CMP     make_minus, 0<br />        JE      not_minus<br />        NEG     CX<br />not_minus:<br /><br />        POP     SI<br />        POP     AX<br />        POP     DX<br />        RET<br /><br />SCAN_NUM        ENDP <br /><br />;//////// RUTINA HEXADECIMAL<br />  <br />Hexa        proc    near<br />            push    bp<br />            mov     bp,sp<br />            mov     al,[bp+4]<br />            shr     al,4<br />            add     al,48<br />            cmp     al,58<br />            js      nible2<br />            add     al,7<br />nible2:     mov     B,al<br />            mov     al,[bp+4]<br />            shl     al,4<br />            shr     al,4<br />            add     al,48<br />            cmp     al,58<br />            js      nible1<br />            add     al,7<br />nible1:     mov     B[1],al<br />            pop     bp<br />            ret<br />Hexa        endp <br /><br />;////////////FIN DEL PROGRAMA<br /><br /><br /><br />.exit<br />
rfgaz ·
Very good, even though I understand very little of it, that's what makes me enjoy looking at the code.<br /><br />
UpecBlack ·
is it for NASM or FASM??
Psymera ·
It looks more like MASM :p
Grupo de WhatsApp