0

每次我尝试运行我的代码时,都会遇到分段错误。谁能指出我正确的方向是什么导致了这种情况?

编译器在 Linux 上,我通过 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

更新:我使用 pop 函数在调用所在的位置添加了对代码的更改,现在它确实摆脱了分段错误,我现在得到输出,但是,不是我想要的值。

输出:

区域:134520364 | 积分:134520380 | 概率:134520396/134520424

区域:134520260 | 积分:134520276 | 概率:134520292/134520320

区域:134520260 | 积分:134520276 | 概率:134520292/134520320

什么时候应该

面积:1 | 点数:17 | 概率:1/64

我没有设置循环,所以我不确定为什么打印了 3 行。

更新2:

通过建议对推送进行了更改,使我知道输出看起来更好...

面积:17 | 点数:1 | 概率:64/134519817

即使应该是:

面积:1 | 点数:17 | 概率:1/64

我如何将它放在堆栈中

1 , 17 , 1 , 64 .... 我的字符串是:

display db "面积:%d | 点数:%d | 概率:%d/%d",10,0

所以看起来它们是随机放置的

我需要添加 mov dword [esp + 4], display 吗?

4

2 回答 2

2

段错误来自不正确地退出程序。 ret不是在 Linux 或 Windows 中退出程序的正确方法。Windows 是ExitProcess,Linux 是系统调用,或者exit从 C 库调用。在您的情况下,您正在链接到要使用的 C 库,printf并且 gcc 将添加在您的代码之前运行的启动代码,因此您必须调用exit以正确终止您的程序。

还有其他问题,但这将解决段错误。另外,按照提到的 mbratch 进行操作,并在调用 printf 后通过推送和调整 esp 来传递参数

于 2013-10-26T04:47:25.170 回答
0

首先,mov dword [esp + #], ...线条会覆盖push ...线条所做的事情,因此您应该摆脱它们。其次,您输出的那些数字看起来像地址 - 实际上,当您执行 ie 时push pi4,您正在推送pi4变量的地址。相反,您应该推送变量的内容,使用push dword [pi4].

于 2013-10-26T05:34:46.037 回答