在Assembly中查询整数时出现分段错误

时间:2014-02-22 01:35:22

标签: assembly segmentation-fault

所以我正在学习英特尔x86程序集,并且我正在尝试向用户查询两个整数,而如果他们输入的整数小于0则拒绝。虽然我仍然会遇到分段错误,但我不确定原因。< / p>

;.........................................................
;.........................................................
; sub-program to read an integer 
segment .Data
readmsg db "Enter two positive integers:", 0
negative_msg db "No, enter a POSITIVE integer.", 0
segment .text

int_cin:

push   ebp
mov    ebp,esp

mov    ecx, 2
mov    eax, readmsg
call   print_string

start:       
call   read_int
mov ebx, eax
cmp ebx, 0
jge skip
mov eax, negative_msg
call print_string
call print_nl
loop start
skip:
push ebx
dec ecx
loop start

pop  ebx
mov [Sec_Int], ebx
pop ebx
mov [First_Int], ebx

pop    ebp
ret

1 个答案:

答案 0 :(得分:0)

我不确定您使用哪种API提供print_stringprint_nlread_int,但我几乎可以肯定您不能指望它的价值在这些调用期间保留ECX寄存器(我记得没有一个调用约定保证)。因此,您的第一个错误是您希望ECX仅由您自己的代码更改,而不是由那些外部函数更改。

如果我是对的并且ECX意外地改变,那么等待ECX变为零的loop指令很可能永远不会停止跳转到相应的标签。这会给你一个无限循环。

进一步看,你会看到在那个循环中你将EBX推送到每次迭代的堆栈。如果循环是无限的,堆栈肯定会溢出,导致分段错误。

P.S。如果第一个loop start没有转到start,因为ECX变为零,执行流程将继续遵循指令,这将推动EBX堆叠,再次减少ECX(现在它为-1),并循环回来开始。下一次ECX将变为零(在理想条件下)并不是那么快。

P.P.S。您似乎混淆了标签地址和存储在这些地址的值,这可能是分段错误的另一个原因。了解您首先将[readmsg]传递给print_string的方式,然后将readmsg传递给相同的函数。看起来很可疑。