sadness uee
sadness uee

Reputation: 21

Comparing integer values in assembly

We are tasked to do compare integer values and print out appropriate prompt to show which values are greater.

The code I made below initializes 'i' and 'j' to 5 and 4, respectively. The objective is to compare "variables" instead of the immediate values itself. So in this example, I put 'i' and 'j' in the cmp, and not 5 and 4.

global _main
extern _printf, _system 

section .text


_main:
; clear screen
    push clr
    call _system
    add esp, 4

;Test prints out i. Successfully does the job.
    push dword [i]          ; why did it work here and not in *cmp*?
    push prompt2
    call _printf      
    add esp, 8

;compare values and do a conditional jump.
    CMP dword [i], dword [j]            ; compares values stored in i and j. i and j are base 10 nums. This is where the error appears.
    JG igreat                           ; jumps if i is greater than j.
    JL jgreat                           ; jumps if j is greater than i.
    JE eks                              ; jumps if i and j are equal.
    ret                                 ; as a measure, this ends the code.

    igreat:                             ; prints out a prompt if i is greater than j.
    push dword [j]
    push dword [i]
    push ibig
    call _printf
    add esp, 16
    ret

    jgreat:                             ; prints out a prompt if j is greater than i.
    push dword [i]
    push dword [j]
    push jbig
    call _printf
    add esp, 16
    ret

    eks:                                ; prints out a prompt if i is equal to j.
    push dword [i]
    push dword [j]
    push ex
    call _printf
    add esp, 16
    ret



last:                                   ; terminates the code
ret

section .data
clr         db "cls",0              
i           dd 5                        ; i is initialized to 5
j           dd 4                        ; j is initialized to 4
prompt2     db "Value is %d",13,10,0
ibig        db "Test 1. Comparisons: %d is bigger than %d",13,10,0
jbig        db "Test 2. Comparisons: %d is bigger than %d",13,10,0
ex          db "Test 3. Comparisons: %d is bigger than %d",13,10,0

Two inquiries I may raise:

  1. CMP dword [i], dword [j] produces an error: invalid combination of opcode and operands; but I successfully recovered values using the printf functions on the previous call/lines of code. Why is that?
  2. I tried to replace dword [j] with an immediate, say, CMP dword [i], 9. It does print out the correct prompt, but makes the program not responding. Why is that?

Please be reminded that I am running Windows 8 Intel 32 bit, this code has been "compiled" in NASM running in DoSBox, and GCC in CMD.

I am a total beginner and any help would be much appreciated. Thank you!

Upvotes: 2

Views: 6225

Answers (1)

Sami Kuhmonen
Sami Kuhmonen

Reputation: 31203

CMP cannot compare two memory locations. It can compare a register to a register, constant or memory and it can compare a memory location to a constant or register. This is why you get an error and it is correct. You have to store the value of one of them into a register and then compare.

The reason why the program is "not responding" is because you mess up the ESP. You push things to stack, call _printf and then for some reason move ESP 16 bytes up. RET will then jump to the first value in stack at that point and I'm sure it's not correct.

You should store the ESP value into EBP on startup and on return restore ESP and then RET.

Upvotes: 6

Related Questions