所以我正在学习英特尔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
答案 0 :(得分:0)
我不确定您使用哪种API提供print_string
,print_nl
和read_int
,但我几乎可以肯定您不能指望它的价值在这些调用期间保留ECX寄存器(我记得没有一个调用约定保证)。因此,您的第一个错误是您希望ECX仅由您自己的代码更改,而不是由那些外部函数更改。
如果我是对的并且ECX意外地改变,那么等待ECX变为零的loop
指令很可能永远不会停止跳转到相应的标签。这会给你一个无限循环。
进一步看,你会看到在那个循环中你将EBX推送到每次迭代的堆栈。如果循环是无限的,堆栈肯定会溢出,导致分段错误。
P.S。如果第一个loop start
没有转到start
,因为ECX变为零,执行流程将继续遵循指令,这将推动EBX堆叠,再次减少ECX(现在它为-1),并循环回来开始。下一次ECX将变为零(在理想条件下)并不是那么快。
P.P.S。您似乎混淆了标签地址和存储在这些地址的值,这可能是分段错误的另一个原因。了解您首先将[readmsg]
传递给print_string
的方式,然后将readmsg
传递给相同的函数。看起来很可疑。