2014-08-29 2 views
0

어셈블리가 처음인데 디버깅 방법을 모르는 문제가 발생했습니다. 나는 커맨드 라인 인자를 취하고 인자에 대한 인자들을 출력하는 아주 간단한 프로그램을 작성하고있다. 목적은 의사 결정과 반복에 익숙해지는 것입니다. 지금까지 모든 것을 하나로 묶어 놓았지만 짝수는 작동하지만 홀수는 작동하지 않습니다. 또한 짝수에 대한 올바른 결과를 생성 할 수 있지만 마지막 검사 후 여전히 segfault로 실행됩니다.값을 비교할 때 세그먼트 오류

 section .bss 
     input: resb 100 
     count: resb 100 


     main: 
       mov ecx,[esp+8]    ;point to command line arguement 
       mov eax,[ecx+4]    ;extract second element 


       push dword eax    ;segfaults without dword. 
       call atoi     ;convert the ascii from cmd line into integer. 
       add esp,4 
       mov dword [input],eax  ;copy original 

       xor edx, edx    ;zero out edx to prevent division error. [2] 
       mov ebx,2 
       div ebx      ;divide eax by ebx. quotient stored in eax, remainder stored in edx. 

       mov [count],eax    ;make a copy of the original argument/2, no number larger can be a factor. 

       jmp checkAgain 

     ret 

     ;strFormat db `Count: %d, Quotient: %d, Remainder: %d, Input: %d, EBX: %d\n`,0 

     true: 
       push ebx 
       push dword [input] 
       push edx 
       push eax 
       push dword [count] 

       push strFormat 
       call printf 
       add esp,16 
       cmp dword [count],0 
       jg checkAgain 
     ret 

     checkAgain: 

       xor edx,edx 
       mov eax,[input] 
       mov ebx,[count] 
       div ebx 
       dec dword [count] 
       cmp edx,0 
       je true 
       mov ecx,dword [count]  
       cmp ecx,0    ;this is where I expect the program to end, but it crashes. 
       jg checkAgain 
     ret 

조립은 매우 어렵습니다. 나는 배울 것이 많아서 어떤 의견이라도 고맙게 생각합니다.

+0

코드에서 홀수에 대해 잘못된 결과를 생성 할 수 없습니다. 번호, 예상 결과 및 실제 결과를 게시물에 추가하십시오. – rkhb

+0

나는 그것을 잘못 설명했다. 잘못된 결과를 생성하지 않으며, 프로그램 끝 부분에서 세분됩니다. – user2325881

답변

1

세그먼트 화 오류는 에 의해 발생합니다. 스택에 6 개의 dword (= 24 bytes)를 푸시므로 call printf 다음에 스택을 지우려면 add esp,24을 사용해야합니다.

코드는 컴파일 할 수 없습니다. 이 사람은 나를 위해 작동 : ret

; Name:  spagfac.asm 
; Assemble: nasm -felf32 spagfac.asm 
; Link:  gcc -m32 -o spagfac spagfac.o 
; Run:  ./spagfac 60 

global main 
extern atoi, printf 

section .bss 
    input: resb 100 
    count: resb 100 

section .data 
    strFormat db `Count: %d, Quotient: %d, Remainder: %d, Input: %d, EBX: %d\n`,0 

section .text 

    main: 
     mov ecx,[esp+8]   ;point to command line arguement 
     mov eax,[ecx+4]   ;extract second element 


     push dword eax   ;segfaults without dword. 
     call atoi    ;convert the ascii from cmd line into integer. 
     add esp,4 
     mov dword [input],eax ;copy original 

     xor edx, edx   ;zero out edx to prevent division error. [2] 
     mov ebx,2 
     div ebx     ;divide eax by ebx. quotient stored in eax, remainder stored in edx. 

     mov [count],eax   ;make a copy of the original argument/2, no number larger can be a factor. 

     jmp checkAgain 

    ret 

    true: 
     push ebx 
     push dword [input] 
     push edx 
     push eax 
     push dword [count] 

     push strFormat 
     call printf 
     add esp,24 
     cmp dword [count],0 
     jg checkAgain 
    ret 

    checkAgain: 

     xor edx,edx 
     mov eax,[input] 
     mov ebx,[count] 
     div ebx 
     dec dword [count] 
     cmp edx,0 
     je true 
     mov ecx,dword [count] 
     cmp ecx,0 
     jg checkAgain 
    ret 

"종료"은 GCC와 함께 작동합니다. LD를 사용한다면 syscall (int 80h/fn 01h)을 사용하여 종료해야합니다.

+0

당신은 분명히 그것에 대해 정확합니다, 나는 스택에서 잘못된 수의 움직임을 보았습니다. 그러나이 수정으로도 segfault는 여전히 발생합니다. – user2325881

+0

@ user2325881 : 코드를 수정하여 내 게시물에 추가했습니다. 어쩌면 잘못된 어셈블러/컴파일러/링커 명령을 사용했을 수도 있습니다. – rkhb

관련 문제