2013-10-26 4 views
0

코드를 실행할 때마다 세그먼트 화 오류가 발생합니다. 아무도이 원인이 될 수있는 올바른 방향으로 나를 가리킬 수 있습니까?인텔 기반 어셈블리 언어 세그먼트 화 오류

컴파일러는 PuTTY를 통해 코드를 실행하고 있습니다.

나는 그것이 mov dword [esp + #]과 관련이 있다고 생각하지만 수정하는 것에 대해서는 알지 못합니다.

%include "asm_io.inc" 
segment .data 
display db "Area: %d | Points: %d | Probability: %d/%d",10,0 
display2 db "Expected Outsome: %d", 0 
radiusone db "Enter number ", 0 
radiustwo db "Enter number ", 0 
radiusthree db "Enter number ", 0 
radiusfour db "Enter number ", 0 
pointsone db "Enter number ", 0 
pointstwo db "Enter number ", 0 
pointsthree db "Enter number ", 0 
pointsfour db "Enter number ", 0 

segment .bss 

r1 resd 1 ;Radius 
r2 resd 1 
r3 resd 1 
r4 resd 1 
p1 resd 1 ;Points 
p2 resd 1 
p3 resd 1 
p4 resd 1 
ca1 resd 1 ;Computed Area 
ca2 resd 1 
ca3 resd 1 
ca4 resd 1 
pi1 resd 1 ;radius*radius 
pi2 resd 1 
pi3 resd 1 
pi4 resd 1 
pb1 resd 1 ;Probability 
pb2 resd 1 
pb3 resd 1 
pb4 resd 1 
eo resd 1 ; Expected Outcome 

segment .text 
     global asm_main 
     extern printf 
asm_main: 
     enter 0,0    
     pusha 

    mov eax, radiusone 
    call print_string 
    call read_int 
    mov [r1], eax 

    mov eax, radiustwo 
    call print_string 
    call read_int 
    mov [r2], eax 

    mov eax, radiusthree 
    call print_string 
    call read_int 
    mov [r3], eax 

    mov eax, radiusfour 
    call print_string 
    call read_int 
    mov [r4], eax 
    ;************************ 

    mov eax, pointsone 
    call print_string 
    call read_int 
    mov [p1], eax 

    mov eax, pointstwo 
    call print_string 
    call read_int 
    mov [p2], eax 

    mov eax, pointsthree 
    call print_string 
    call read_int 
    mov [p3], eax 

    mov eax, pointsfour 
    call print_string 
    call read_int 
    mov [p4], eax 
    ;************************ 

    mov eax, [r1] 
    imul eax, [r1] 
    mov [pi1], eax 

    mov eax, [r2] 
    imul eax, [r2] 
    mov [pi2], eax 

    mov eax, [r3] 
    imul eax, [r3] 
    mov [pi3], eax 

    mov eax, [r4] 
    imul eax, [r4] 
    mov [pi4], eax 
    ;********************** 

    mov eax, [r1] 
    mov [ca1], eax 

    mov eax, [ca2] 
    sub eax, [pi1] 
    mov [ca2], eax 

    mov eax, [ca3] 
    sub eax, [pi2] 
    mov [ca3], eax 

    mov eax, [ca4] 
    sub eax, [pi3] 
    mov [ca4], eax 
    ;******************** 

    mov eax, [r1] 
    imul eax, [p1] 
    mov [pb1], eax 

    mov eax, [r2] 
    imul eax, [p2] 
    mov [pb2], eax 

    mov eax, [r3] 
    imul eax, [p3] 
    mov [pb3], eax 

    mov eax, [r4] 
    imul eax, [p4] 
    mov [pb4], eax 
    ;*********************** 

    mov eax, [pb1] 
    add eax, [pb2] 
    add eax, [pb3] 
    add eax, [pb4] 
    mov [eo], eax 
    ;************************ 

    sub easp 10h 

    push dword [pi4] 
    push dword [ca1] 
    push dword [p1] 
    push dword [r1] 


    mov dword [esp], display 
    call printf 
    add esp, 10h  


    popa 
    mov  eax, 0   
    leave      
    ret 

업데이트 : 나는 팝업 기능 아래로 호출이 곳의 사용으로 코드를 변경 추가하고 지금은 세그먼트 오류를 ​​제거 않으며, 지금은 출력, 그러나, 값 나 '를 얻을 수 좋아해.

출력 :

지역 : 134,520,364 | 포인트 : 134520380 | 확률 : 134520396/134520424

면적 : 134520260 | 포인트 : 134520276 | 확률 : 134520292/134520320

면적 : 134520260 | 포인트 : 134520276 | 확률 : 134,520,320분의 134,520,292

그것이 있어야

지역 : 1 | 포인트 : 17 | 확률 : 1/64

루프 설정이 없으므로 3 줄이 인쇄 된 이유가 확실치 않습니다.

UPDATE2 : I 출력이 더 나은 찾고 얻을 알고 만든 제안으로 밀어

만들어진 변경 ...

지역 : 17 | 점수 : 1 | 확률 : 134,519,817분의 64

해야 비록 :

지역 : 1 | 포인트 : 17 | 확률 : 1/64

내가 스택을 얼마나

1, 17, 1, 64 .... 그리고 내 문자열은 다음과 같습니다

디스플레이 dB " 지역 : % d의 | 포인트 : % d의 | 확률 : % d 개들이 무작위로 배치처럼

10,0 그래서 그것은 본다/% d 개 ",

mov dword [esp + 4], display을 추가해야하나요?

+0

'printf' 호출을 위해 스택으로 매개 변수를 옮기는 것 같습니다. 스택에있는 다른 항목을 덮어 쓰고 있기 때문에 그렇게 할 수 없습니다. 스택에 매개 변수를'push '하고, 호출을 한 다음, push를하기 전에 스택 포인터를 원래 위치로 복원해야한다. – lurker

+0

나는 당신이 말했던 것을했는데 그것은 segmentation fault를 제거하고 잘못된 output을 출력했다. 나는 내 코드를 살펴 봤는데 그 숫자가 왜 그 숫자인지 확신 할 수 없었다. 그 숫자가 기억 장소라고 추측 할 수 있습니까? – user2922055

답변

2

seg 오류는 프로그램을 잘못 종료했을 때 발생합니다. ret은 Linux 또는 Windows에서 프로그램을 종료하는 적절한 방법이 아닙니다. Windows는 ExitProcess이고 Linux는 시스템 호출이거나 C 라이브러리의 exit에 대한 호출입니다. 귀하의 경우에는 printf을 사용하기 위해 C 라이브러리에 연결하고 gcc는 코드 전에 실행되는 시작 코드를 추가하므로 프로그램을 올바르게 종료하려면 exit으로 전화해야합니다.

다른 문제가 있지만 이로 인해 seg 오류가 해결됩니다. 또한 mbratch가 언급 한대로 printf를 호출 한 후 esp를 밀고 조정하여 매개 변수를 전달합니다.

0

먼저 mov dword [esp + #], ... 행이 push ... 행을 덮어 쓰므로 해당 행을 제거해야합니다. 둘째, 출력하는 숫자는 주소처럼 보입니다. 실제로는 push pi4을 입력하면 pi4 변수의 주소를 푸시합니다. 대신 push dword [pi4]과 함께 변수 내용을 푸시해야합니다.

+0

감사합니다. 나는 지금 바른 길에있다. 업데이트 예정. 여전히 약간 섞여 있지만 진행중인 작업 – user2922055