如何在 nasm 64 位中跳转到间接注册
How to do jump to register indirect in nasm 64 bit
我在 32 位程序(Forth 解释器)中有以下 nasm 代码
MOV EBP, LONG[USINI+(CW*(3))] ;Return stack
...
LODSD ; NEXT
JMP LONG[EAX]
最后一条指令取AX指向的地址,跳转到该地址。
64 位的等效代码不再 assemble:
MOV RBP, QWORD[USINI+(CW*(3))] ;Return stack
...
LODSD ; NEXT
JMP QWORD[RAX]
在 NASM 64 位中指定此指令的正确方法是什么?
当然,这可能是 nasm 中的一个缺陷,但我如何确定它呢?
(完全相同的代码 assembles 在 fasm 中效果很好。)
(第一个QWORD被nasm接受)
消息是:"ci86.lina64.asm:318: error: impossible combination of address sizes"
318是JMP的那一行。
nasm版本is:NASM版本2.10.01编译于Jun 14 2012
省略 "QWORD" 会给出相同的错误消息,此外:
"ci86.lina64.asm:318: error: impossible combination of address sizes"
正如 Jester 指出的那样
jmp [rax]
是正确的,而
jmp qword[rax]
是允许的。
如果它失败了,你做错了什么。
在这种情况下,问题是缺少
BITS 64
关键字。
为了获得 64 位目标文件,您需要在调用 nasm 的命令行中指定 -felf64 作为架构
nasm x.asm -felf64 -g -o x.o
在这种情况下,隐含了 BITS 64。问题当然是您永远无法通过组装并且无法发现该错误。
首先,jmp [mem]
是一个memory-indirect跳转(设置RIP=从内存加载的指针)。 jmp rax
将是 register-indirect 跳转,设置 RIP = RAX
.
你没说第318行是哪一行,你确定是jmp
吗?因为该行的语法看起来没有任何问题。
你的代码还在64位模式下使用32位指针吗?这是可能的,只要您坚持低 4GB 的地址 space,以便地址适合 32b。更改它需要 re-sizing 所有存储指针的数据结构。
请注意,默认情况下,堆栈地址 而不是 在低 32b 中。使用 32 位 address-size 前缀(例如 mov rdx, [eax]
)sign-extends 地址。
MOV EBP, QWORD[USINI+(CW*(3))] ; you probably need RBP, or else this should still be a 32bit load. If it's 64bit, I hope you fixed the address calculations to account for each element being wider.
...
LODSD ; This a 32bit load, zeroing the upper32 of RAX.
JMP QWORD[RAX]
您是否需要增加 rsi
,或者您是否可以在 jmp 之前使用 mov eax, [rsi]
? lodsd
和 lodsq
在 Intel 上只有 2 微指令,所以如果您确实需要这两种效果,它们实际上是一个不错的选择。
我在 32 位程序(Forth 解释器)中有以下 nasm 代码
MOV EBP, LONG[USINI+(CW*(3))] ;Return stack
...
LODSD ; NEXT
JMP LONG[EAX]
最后一条指令取AX指向的地址,跳转到该地址。 64 位的等效代码不再 assemble:
MOV RBP, QWORD[USINI+(CW*(3))] ;Return stack
...
LODSD ; NEXT
JMP QWORD[RAX]
在 NASM 64 位中指定此指令的正确方法是什么? 当然,这可能是 nasm 中的一个缺陷,但我如何确定它呢?
(完全相同的代码 assembles 在 fasm 中效果很好。)
(第一个QWORD被nasm接受)
消息是:"ci86.lina64.asm:318: error: impossible combination of address sizes"
318是JMP的那一行。
nasm版本is:NASM版本2.10.01编译于Jun 14 2012
省略 "QWORD" 会给出相同的错误消息,此外: "ci86.lina64.asm:318: error: impossible combination of address sizes"
正如 Jester 指出的那样
jmp [rax]
是正确的,而
jmp qword[rax]
是允许的。 如果它失败了,你做错了什么。
在这种情况下,问题是缺少
BITS 64
关键字。
为了获得 64 位目标文件,您需要在调用 nasm 的命令行中指定 -felf64 作为架构
nasm x.asm -felf64 -g -o x.o
在这种情况下,隐含了 BITS 64。问题当然是您永远无法通过组装并且无法发现该错误。
首先,jmp [mem]
是一个memory-indirect跳转(设置RIP=从内存加载的指针)。 jmp rax
将是 register-indirect 跳转,设置 RIP = RAX
.
你没说第318行是哪一行,你确定是jmp
吗?因为该行的语法看起来没有任何问题。
你的代码还在64位模式下使用32位指针吗?这是可能的,只要您坚持低 4GB 的地址 space,以便地址适合 32b。更改它需要 re-sizing 所有存储指针的数据结构。
请注意,默认情况下,堆栈地址 而不是 在低 32b 中。使用 32 位 address-size 前缀(例如 mov rdx, [eax]
)sign-extends 地址。
MOV EBP, QWORD[USINI+(CW*(3))] ; you probably need RBP, or else this should still be a 32bit load. If it's 64bit, I hope you fixed the address calculations to account for each element being wider.
...
LODSD ; This a 32bit load, zeroing the upper32 of RAX.
JMP QWORD[RAX]
您是否需要增加 rsi
,或者您是否可以在 jmp 之前使用 mov eax, [rsi]
? lodsd
和 lodsq
在 Intel 上只有 2 微指令,所以如果您确实需要这两种效果,它们实际上是一个不错的选择。