【发布时间】:2023-12-28 10:42:01
【问题描述】:
所以我最近再次转到 nasm 并尝试构建一些基本的东西(putc 和 puts)。
Putc 工作正常,但问题是在我在puts 中调用putc 后,putc 中的ret 不会返回到由puts 推入堆栈的ip 等等puts 中不再执行指令(在 gdb 中调试了该部分)。
msg db "Welcome!", 0ah, 0dh, 0h
putc:
push ebp
mov esp, ebp
mov ah, 0ah
; al is set before
mov bh, 0
mov bl, 0
mov cx, 1
int 10h
ret
puts:
push ebp
mov esp, ebp
mov ebx, msg
dec ebx
puts_l:
inc ebx
mov al, [ebx]
call putc
cmp al, 0h
jne puts_l
ret
这显然不是最好的,但我想我在某个地方有误解。我可以想象一个寄存器会被 putc 覆盖,但这并不能解释为什么 putc 中的 ret 不会返回到 puts
我还应该提到我正在使用 x86。
【问题讨论】:
-
您可能过于频繁地推送 ebp 几次。这可能会破坏
ret的期望,即ip在某种程度上是堆栈中的下一个项目 -
这实际上是有道理的。 Tho,如果我想创建堆栈帧,我该怎么办?据我所知,这就是这样做的方法。我认为 ret 会为我完成清除堆栈框架的工作。如果没有,我可能不得不使用
leave。 -
ret就是 x86 拼写pop ip(或 32 位代码中的pop eip)的方式。它并不神奇地知道返回哪里,[E/R]SP 必须已经指向一个返回地址。 -
是的,但不应该调用push当前ip然后将ip更改为新地址?这就是你的评论让我有点困惑的地方。
-
是的,
call推送当前的eip(所谓的返回地址)并跳转到被调用的地址,但是这个地址的第一件事就是你的@987654340 @,所以当你执行ret时,eip是从这个推送的ebp加载的,而不是上面预期的返回地址。