如何强制相对偏移的值?
我知道该怎么做:jmp label_name
想做的事:jmp $0x01
您可以使用相对跳转,例如
jmp $+5
它相对于跳跃的开始。
语法问题... Nasm 将使用“$ + 5”,(G)将使用“. + 5”,并且可能还需要一个“$”(?)。我从原始标签中了解到,我们使用的是 Nasm?那么“$ + 5”应该是正确的,但可能不会做你想做的事。asm 语法将是“jmp target”(或 Gas 的“jmp $target”?),您会在反汇编中看到相同的内容……但请仔细查看正在生成的字节。“jmp”操作码后面是“到目标的距离”,而不是“目标”!如果您想编写“到目标的距离”,我认为您需要使用“db 0xE8”(或适当的操作码),然后是“db(或 dw 或 dd)0x??” (我认为,Gas 是“.byte”或“.long”)。这可能不是你想要做的。
最好的,弗兰克
GAS 和 NASM 没有直接设置 rel8 或 rel32 位移的语法,只有目标地址。(例如jmp +0
被解释为跳转到绝对地址 0,或语法错误)。
.byte
您可以使用/ .long
(GAS) 或db
(NASM 和大多数其他非 GAS x86 汇编程序)手动对其进行编码。请注意,相对分支位移是相对于分支指令的结尾的。
db 0xEB, 0x01 ; jmp short +1 over the 1-byte nop
nop
jump_target:
db 0xE9
dd -5 ; jmp near -5 also jump backwards to jump_target, i.e. to itself
(GAS 将是相同的,但使用.byte
and.long
而不是db
and dd
)
或者,使用语法来描述相对于行首的地址
jmp short $+3 ; rel8 = +1 NASM, forcing the jmp size to 2 bytes
jmp .+3 # rel8 = +1 GAS
$ 究竟是如何在 NASM 中工作的?显示了手动编码分支以到达给定目标、$
从目标地址中减去(当前输出位置)并调整分支长度的示例。
这里我们需要考虑分支长度来获得所需的相对偏移编码,因为我们的参考点$ + x
是指令的开始,而不是结束。我们可以在最后加上一个标签:
jmp .rel_anchor + 123 ; rel8= +123 NASM local label
.rel_anchor:
jmp 1f + 123; 1: # GAS local label on the same line but a separate statement
1: # It might be more readable to put the label here.
这确实有效,我们eb 7b
从 GAS 获得。
这是我为了好玩而制作的示例用法。(使用 NASM)
BITS 32
segment .text
global _start
_start:
jmp tmp
PUSH 0x68732f
PUSH 0x6e69622f
LEA EBX,[ESP]
; ...
_jumpstop:
tmp equ ($ - _start)
这样一旦编译它就变成
00000000 E90D000000 jmp 0x12
00000005 682F736800 push dword 0x68732f
0000000A 682F62696E push dword 0x6e69622f
0000000F 8D1C24 lea ebx,[esp]
这样跳跃在之后立即着陆lea ebx,[esp]