2011-12-21 3 views
0

다음 코드를 감안할 때 작동하지 않습니다전화는

.globl main 
    .type main, @function 
input: .string "%d" 
main: 

     pushl %ebp   # save the old frame pointer 
     movl %esp,%ebp  # create the new frame pointer 

     movl $0,%eax 
     addl $-4 ,%esp  # moving down the stack 
     pushl %esp   # push the address of esp to the stack in order to store the number given by the user 
     pushl $input # push to the stack the format of the input 
     call scanf   # call scanf to get a number from the user 
     addl $8,%esp   # clear the stack 
     movl (%esp),%eax  # get the selection from the user 


     subl $50,%eax 
     jmp  *.switching(,%eax,4) 


.section .rodata 
    .align 4 

.switching: 

    .long .L1 
    .long .L2 
    .long .L3 
    .long .L4 

.text 

.L1: 
    call case1 
    jmp  .quitTheProgram 
.L2: 
    call case2 
    jmp  .quitTheProgram 
.L3: 
    call case 
    jmp  .quitTheProgram 
.L4: 
    call case4 
    jmp  .quitTheProgram 



case1: 

      pushl %ebp   # save the old frame pointer 
      movl %esp,%ebp  # create the new frame pointer 
# 
# code of case1 
# 
      movl %ebp,%esp  # restore the old ebp 
      popl %ebp   # restore the old stack pointer and release all used memory 
      ret      # return to caller function (OS) 

사용자 프레스 번호를 50-54 사이. 문제는 (예를 들어) 50 을 누른 후입니다. case1로 건너 뛰고 코드 자체가 아니라 ret 줄로 바로 이동 한 다음 코드가 멈추고 case1을 종료합니다 (나머지 경우).

무슨 문제 일 수 있습니까?

감사합니다, 론

+0

결과 값을 % eax로'popl'합니다. 그렇지 않으면 스택 포인터가 4가됩니다. 또한 추가 브라 우니 점에 대해서'.quitTheProgram'의 주소를'jmp'가되기 전에 스택에 놓을 수 있습니다 - 그래서 case handler 코드는'ret'를 직접적으로합니다. 그러나 이들 중 어느 것도 문제를 해결하지 못합니다. –

답변

0

문제 나 케이스 가구 1로 이동,하지만 코드 자체에 있지만, 바로 그냥 내장

RET 라인에 50 (예)를 눌러 이후 GDB에서 코드를 실행하여 리눅스에서 코드를 실행했는데 이 아니고 동작을 관찰했습니다.

실제로 관찰 한 내용을 잘못 해석하고있는 것 같습니다.

관련 문제