thetipsyhacker
thetipsyhacker

Reputation: 1422

cmp with any value equals 0

I am trying to create a switch statement in assembly; however, I seem to always get stuck on the first case, no matter what the value is:

SECTION .data
    newLine    db  0xA,0xD
    NewLen     equ $- newLine

    nvalue     dw  2          ; nth number for case

    msg0       db  'a', 0xa 
    msg1       db  'b', 0xa 
    msg2       db  'c', 0xa  
    msg3       db  'd', 0xa 
    defaultMsg db  'e'

SECTION .text
    global  _start

    _start:
        mov eax, nvalue

        cmp eax, 0
        je  case0
        cmp eax, 1
        je  case1
        cmp eax, 2
        je  case2
        cmp eax, 3
        je  case3

        case0:
            mov  edx, 2
            mov  eax, 4
            mov  ebx, 1
            mov  ecx, msg0        
            mov  edx, 1        
            int  80h
            call printNL
            call quit
        case1:
            mov  edx, 2
            mov  eax, 4
            mov  ebx, 1
            mov  ecx, msg1        
            mov  edx, 1        
            int  80h
            call printNL
            call quit
        case2:
            mov  edx, 2
            mov  eax, 4
            mov  ebx, 1
            mov  ecx, msg2        
            mov  edx, 1        
            int  80h
            call printNL
            call quit
        case3: 
           mov  edx, 2
           mov  eax, 4
           mov  ebx, 1
           mov  ecx, msg3        
           mov  edx, 1        
           int  80h
           call printNL
           call quit

        mov  edx, 2
        mov  eax, 4
        mov  ebx, 1
        mov  ecx, defaultMsg        
        mov  edx, 1        
        int  80h
        call printNL
        call quit

    printNL:
        mov edx, NewLen
        mov ecx, newLine
        mov ebx, 1       
        mov eax, 4      
        int 80h

    quit:
        mov ebx, 0
        mov eax, 1
        int 80h
        ret

The string output is always 'a' (case0 for when the nvalue variable is 0). Why is it doing this when nvalue is 2?

Upvotes: 1

Views: 299

Answers (2)

Ruslan
Ruslan

Reputation: 19130

        mov eax, nvalue

        cmp eax, 0
        je  case0
        cmp eax, 1
        je  case1
        cmp eax, 2
        je  case2
        cmp eax, 3
        je  case3

        case0:

What this code does is

  1. Load the address of nvalue into eax.
  2. Compare this address with 0, 1, 2 and 3.
  3. If the comparison with 1, 2 or 3 succeeds, jump away to corresponding labels.
  4. Otherwise, jump or fall through to case0.

What you actually want, first of all, is to read the value of nvalue into eax. And this is done by

mov eax, [nvalue]

if you had nvalue defined with dd. If you leave it as it's now, with dw, then the loading could be like

movzx eax, word [nvalue]

And the second point, you may want to add a jump away before the case0 label, if you don't want to fall through to it when all comparisons fail.
Alternatively place the block where you print the defaultMsg, between je case3 ... case0:. This way you shave off the extra jmp.

Upvotes: 4

mevets
mevets

Reputation: 10445

replace:
    nvalue     dw  2          ; nth number for case
with:
    nvalue     dd  2          ; nth number for case

dos asm is quirky.

Also, you might want to add a default case -- that is why it is falling through.

Upvotes: -3

Related Questions