Search code examples
assemblyx86masmirvine32

Adding and Subtracting in Assembly issue


The following is an example code I am trying to compile and execute so I can have a better understanding of arithmetic in Assembly. This problem I am having is why am I getting -32641 as the value and not -36? Thank you. EDITED

TITLE  Addition and Subtraction        (AddSub3.asm)

; Chapter 4 example. Demonstration of ADD, SUB,
; INC, DEC, and NEG instructions, and how
; they affect the CPU status flags.
; Last update: 2/1/02

INCLUDE Irvine32.inc

.data
Rval SDWORD ?
Xval SDWORD 26
Yval SDWORD 30
Zval SDWORD 40

.code
main PROC

    ; INC and DEC
    mov ax,1000h
    inc ax      ; 1001h
    dec ax      ; 1000h

    ; Expression: Rval = -Xval + (Yval - Zval)
    mov  eax,Xval
    neg  eax        ; -26
    mov  ebx,Yval
    sub  ebx,Zval       ; -10
    add  eax,ebx
    mov  Rval,eax       ; -36

    ; Zero flag example:
    mov cx,1
    sub cx,1        ; ZF = 1
    mov ax,0FFFFh
    inc ax      ; ZF = 1

    ; Sign flag example:
    mov cx,0
    sub cx,1        ; SF = 1
    mov ax,7FFFh
    add ax,2        ; SF = 1

    ; Carry flag example:
    mov al,0FFh
    add al,1        ; CF = 1,  AL = 00

    ; Overflow flag example:
    mov  al,+127
    add  al,1       ; OF = 1
    mov  al,-128
    sub  al,1       ; OF = 1

    call writeint
    exit
main ENDP
END main

Solution

  • The first google hit for Irvine32 writedec tells you it takes an unsigned arg, and that WriteInt takes a signed 32-bit argument.


    Since these functions print the full 32-bit eax register, this means you need your number sign-extended into the full eax.

    The value you print is 0xffff807f (in hex). That's 4294934655 - 2^32 = -32641 interpreted as a signed integer (2's complement, google it).

    Irvine32 functions take their first arg in eax, IIRC.

    You run several instructions that modify AX, and then that modify AL, after having a small negative integer in eax, so the upper 16 bits are 0xffff. I didn't work through the details of what your later instructions do to the low 2 bytes, and then 1 byte of eax, but it doesn't look very sane.

    I'm assuming you didn't realize that AX and AL are subsets of EAX, or that writing them just leaves the rest of EAX unmodified.

    See the for more info about it. Also the tag wiki for links that will help correct other basic misunderstandings before they cause you problems. :)