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

How can I jump to a specific line without using labels?

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

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

bar:
mov ax,2
ret (-2)

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

你不能,x86 指令是可变长度的。没有办法知道在 call.

之前向后退 2 条指令可以将 return 地址减少多少

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

的最后一个字节

从已知的函数开始标签解码转发是像 GDB 这样的调试器所做的。但是扫描一个符号 table 并进行反汇编太重了,我想无论你在做什么都不实用。


我唯一想到的是你的调用序列非常严格,所以它总是固定的字节数;例如这里你在 call bar 之前使用了两个 3 字节的指令(call rel16mov ax, imm16)。而 call bar 本身也是 3 个字节。

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


顺便说一句,你这样做的方法是修改堆栈上的 return 地址:

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

或者如果您已将 BP 设置为帧指针,则相对于 BP 解决它,例如 sub word [bp+2], 9


请参阅 了解在不添加更多指令的情况下使指令变长的技术,以防您想在调用前使用像 mov cx, bx 这样的较短指令。例如您可以改为使用 lea cx, [byte 0 + bx](NASM 语法:byte 0 强制使用 0 的 disp8,因此编码为 8D 4F 00)。