; File: switch.asm
;
; Assembly code to be generated for a switch statement.
; (This code was hand written.)
; 
;   switch ( x ) {
;    case 17: printf("Case 17\n") ; break ;
;    case 23: printf("Case 23\n") ; break ;
;    case 35: printf("Case 35\n") ; break ;
;    default: printf("Default case\n") ; 
;  }
;

; Declare some external functions
;
        extern printf          ; the C function, we'll call

        SECTION .text           ; Code section.

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

        push    dword 23        ; simulate value of x
        jmp     near switch_init

switch_case_1:
        push    dword msg17
        call    printf
        add     esp, 4
        jmp     near switch_end

switch_case_2:
        push    dword msg23
        call    printf
        add     esp, 4
        jmp     near switch_end

switch_case_3:
        push    dword msg35
        call    printf
        add     esp, 4
        jmp     near switch_end

switch_default_case:
        push    dword msgdf
        call    printf
        add     esp, 4
        jmp     near switch_end

switch_init:
        pop     eax                     ; loop init
        mov     edx, switch_table_begin

switch_loop:
        cmp     edx, switch_table_end   ; end?
        jae     switch_default_case
        cmp     eax, [edx]              ; compare with case
        je      switch_go               ; found matching case
        add     edx, 8                  ; next case
        jmp     switch_loop

switch_go:
        jmp     near [edx + 4]          ; if =, jump to statement
switch_end:
                
        mov     esp, ebp                ; takedown stack frame
        pop     ebp                     ;   same as "leave"

        ret


        SECTION .data                   ; Data section

msg17:  db "Case 17", 10, 0
msg23:  db "Case 23", 10, 0
msg35:  db "Case 35", 10, 0
msgdf:  db "Default case", 10, 0

switch_table_begin:
        dd      17, switch_case_1
        dd      23, switch_case_2
        dd      35, switch_case_3
switch_table_end:

