每次我尝试运行我的代码时,我都会遇到段错误。任何人都可以指出我正确的方向,了解可能导致这种情况的原因吗?
编译器在 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 "Area: %d | Points: %d | Probability: %d/%d",10,0
所以看起来它们是随机放置的
我需要添加 mov dword [esp + 4], display
吗?
最佳答案
段错误来自不正确地退出程序。 ret
不是在 Linux 或 Windows 中退出程序的正确方法。 Windows 是 ExitProcess
而 Linux 是系统调用,或者从 C 库调用 exit
。在您的情况下,您正在链接到 C 库以使用 printf
并且 gcc 将添加在您的代码之前运行的启动代码,因此您必须调用 exit
以正确终止您的程序。
还有其他问题,但这将修复段错误。另外,按照 mbratch 提到的那样,在调用 printf 之后通过推送和调整 esp 来传递参数
关于linux - 基于Intel的汇编语言段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19602430/