1

I am "successfully" getting user input, however my switchCase function always falls to the defaultCase:

extern  printf      ; the C function, to be called

SECTION .data
    promptNVal: db 'Enter nth case number: ' ;Ask user for nth case number
    promptNValLen: equ $-promptNVal

    nvalue: dd 2
    val1: dd 4
    val2: dd 1024
    val3: dd 32767
    defaultMsg: db "Default: ", 0

    belowMinMsg: db "Number cannot be below 0.", 0
    aboveMaxMsg: db "Number cannot be above 65535.", 0

    intFmt0:    db "Case0: %d", 10, 0 ; The printf format, "\n",'0' for case 0
    intFmt1:    db "Case1: %d", 10, 0 ; The printf format, "\n",'0' for case 1
    intFmt2:    db "Case2: %d", 10, 0 ; The printf format, "\n",'0' for case 2
    intFmt3:    db "Case3: %d", 10, 0 ; The printf format, "\n",'0' for case 3
    strFmt: db "%s", 10, 0 ; The printf format, "\n",'0' for strings
    intValidationError: db "Error. Number entered was: %d", 10, 0 ; The printf format, "\n",'0' for strings

SECTION .text
global  main

main:
    push    ebp     ; set up stack frame
    mov     ebp,esp

    ;prompt nvalue
    mov eax, 4 
    mov ebx, 1     ; descriptor value for stdout
    mov ecx, promptNVal 
    mov edx, promptNValLen
    int 0x80
    
    ;Read and store nth number 
    mov eax, 3 
    mov ebx, 0     ; descriptor value for stdin
    mov ecx, nvalue
    mov edx, 10
    int 0x80 

    cmp eax, 0 ; check if nvalue if below 0
    jl belowMin ; print below 0 message in belowMin function
    cmp eax, 65535 ; check if nvalue if above 0
    jg aboveMax ; print above maximum message in aboveMax function
    jmp switchCase  ; otherwise, jump to switchCase
    
    case0:
        mov eax, [val1]   
        mov ebx, [val2]
        mul ebx
        push eax
        push    dword intFmt0   ; address of string for case0
        call    printf      ; Call C function
        add     esp, 12     ; pop stack 3 push times 4 bytes

        mov     esp, ebp    ; takedown stack frame
        pop     ebp     ; same as "leave" op
        call quit
    case1:
        mov eax, [val2]   
        mov ebx, [val3]
        mul ebx
        push eax
        push    dword intFmt1   ; address of string for case1
        call    printf      ; Call C function
        add     esp, 12     ; pop stack 3 push times 4 bytes

        mov     esp, ebp    ; takedown stack frame
        pop     ebp     ; same as "leave" op
        call quit
    case2:
        mov eax, [val3]   
        mov ebx, [val1]
        sub eax, ebx
        push eax
        push    dword intFmt2   ; address of string for case2
        call    printf      ; Call C function
        add     esp, 12     ; pop stack 3 push times 4 bytes

        mov     esp, ebp    ; takedown stack frame
        pop     ebp     ; same as "leave" op
        call quit
    case3: 
        mov eax, [val1]   
        mov ebx, [val3]
        sub eax, ebx
        push eax
        push    dword intFmt3   ; address of string for case3
        call    printf      ; Call C function
        add     esp, 12     ; pop stack 3 push times 4 bytes

        mov     esp, ebp    ; takedown stack frame
        pop     ebp     ; same as "leave" op
        call quit
    defaultCase:
        mov eax, defaultMsg    
        push    dword defaultMsg    ; value of variable defaultMsg
        push    dword strFmt    ; address of string for defaultCase
        call    printf      ; Call C function
        add     esp, 12     ; pop stack 3 push times 4 bytes

        mov     esp, ebp    ; takedown stack frame
        pop     ebp     ; same as "leave" op
        call quit

belowMin:
    mov eax, belowMinMsg    
    push    dword belowMinMsg   ; value of variable belowMinMsg
    push    dword strFmt    ; address of ctrl string
    call    printf      ; Call C function
    add     esp, 12     ; pop stack 3 push times 4 bytes

    mov     esp, ebp    ; takedown stack frame
    pop     ebp     ; same as "leave" op
    call quit

aboveMax:
    mov eax, aboveMaxMsg    
    push    dword aboveMaxMsg   ; value of variable aboveMaxMsg
    push    dword strFmt    ; address of ctrl string
    call    printf      ; Call C function
    add     esp, 12     ; pop stack 3 push times 4 bytes

    mov     esp, ebp    ; takedown stack frame
    pop     ebp     ; same as "leave" op
    call quit

switchCase:
    mov eax, [nvalue] ; get value of nvalue
    cmp eax, 0 ; check if nvalue is 0
    je case0 ; if case0 to case0 function
    cmp eax, 1  ; check if nvalue is 1
    je case1 ; if case1 to case1 function
    cmp eax, 2  ; check if nvalue is 2
    je case2 ; if case2 to case2 function
    cmp eax, 3  ; check if nvalue is 3
    je case3 ; if case3 to case3 function
    jmp defaultCase ; otherwise, go to defaultCase function

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

The terminal output is always "Default: " no matter what I input for the nvalue. Why is this happening?

UPDATE

I've tried printing nvalue inside of defaultCase and looks like I'm getting 2608 for 0, 2609 for 1, 2610 for 2, 2611 for 3, etc.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
thetipsyhacker
  • 1,402
  • 4
  • 18
  • 39
  • 2
    There's at least two ways to handle this. (1) Single step and verify that each instruction has the effect you want, and you'll find where it first goes wrong -- fix that then repeat; (2) Write the shortest possible program that does each little thing you're trying to do, and when they're working, string them together in a next program. If it were me I would focus on the first `int 0x80` read call to verify that you're getting what you want in `nvalue` and/or `eax`. Are you? – Erik Eidt Oct 02 '20 at 21:18
  • @ErikEidt No, I'm not. I removed all user inputs except for nvalue, and I'm printing it in the defaultCase. I'm getting 2608 when I input 0, 2609 for 1, 2610 for 2, and 2611 for 3. Not sure what's going on. – thetipsyhacker Oct 02 '20 at 21:35
  • 1
    `2608 = 0x0A30` which due to endianness is `0x30 0x0A` which is ascii code for `0` and line feed. Meaning, `read()` gives you text, not numbers. – Jester Oct 02 '20 at 21:36
  • 1
    I see no debugging has happened, nor is this a minimal example, please update the question with a minimal example and indicate the debugging you did to try to isolate the problem. – old_timer Oct 02 '20 at 21:39
  • @Jester I think I just need to convert ascii to integers then. what's the best way to implement that? – thetipsyhacker Oct 02 '20 at 22:10
  • Looks like `add esp, 12` is popping too much, saved only by `mov esp, ebp` immediately overwriting ESP with the correct value. (But still leaves a 1 instruction window where a signal handler could step on a stack value.) – Peter Cordes Oct 02 '20 at 22:45
  • See the multi-digit number FAQ entry in https://stackoverflow.com/tags/x86/info, specifically [NASM Assembly convert input to integer?](https://stackoverflow.com/a/49548057). (Or call `atoi` if you want to let the C library do it for you, or use `scanf` instead of making a raw `read` system call.) – Peter Cordes Oct 02 '20 at 22:50

0 Answers0