gpt4 book ai didi

assembly - 如何在不使用标签的情况下跳转到特定行?

转载 作者:行者123 更新时间:2023-12-02 21:54:16 27 4
gpt4 key购买 nike

假设我有一个返回的调用函数,我可以使它返回到返回地址之前的 x 行吗?例如。

call foo --> line 72 - calling bar will return here.
mov ax,1
call bar --> line 74

bar:
mov ax,2
ret (-2)

我的目标是创建一个可调用函数,该函数始终返回到调用地址之前的 2 行,而无需使用十亿个标志和标签。

最佳答案

不能,x86 指令的长度是可变的。无法知道在调用之前将返回地址递减多少才能向后移动 2 个指令。

即使您愿意编写反汇编程序/解码器,也无法明确向后解​​码 x86 指令。例如如果您返回一个字节并看到 0x90,您不知道这是 NOP 还是 add dx, 0x9000 的最后一个字节。

从已知的函数开始标签向前解码是 GDB 等调试器所做的事情。但我认为,扫描符号表和反汇编对于您正在做的任何事情来说都太繁重了,不切实际。

<小时/>

我唯一想到的就是你的调用序列非常严格,因此字节数始终是固定的;例如这里,您在 call bar 之前使用了两条 3 字节指令(call rel16mov ax, imm16)。 调用栏本身也是 3 个字节。

或者总是在返回地址之前返回固定数量的字节,并让调用者选择在该窗口中放入哪些/多少条指令。

<小时/>

顺便说一句,执行此操作的方法是修改堆栈上的返回地址:

pop ax            ; could use any register that your function destroys
sub ax, 9
push ax
ret

或者如果您已将 BP 设置为帧指针,则相对于 BP 对其进行寻址,例如 sub word [bp+2], 9

<小时/>

参见What methods can be used to efficiently extend instruction length on modern x86?了解在不添加更多指令的情况下使指令更长的技术,以防您想在调用之前使用较短的指令,例如 mov cx, bx。例如您可以使用 lea cx, [byte 0 + bx] (NASM 语法:byte 0 强制 disp8 为 0,因此编码为8D 4F 00)。

关于assembly - 如何在不使用标签的情况下跳转到特定行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59529419/

27 4 0