Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 如何在nasm 64位中跳转到寄存器间接_Assembly_64 Bit_Nasm - Fatal编程技术网

Assembly 如何在nasm 64位中跳转到寄存器间接

Assembly 如何在nasm 64位中跳转到寄存器间接,assembly,64-bit,nasm,Assembly,64 Bit,Nasm,我在一个32位程序(一个Forth解释器)中有以下nasm代码 最后一条指令获取AX指向的地址并跳到该地址。 64位的等效代码不再汇编: MOV RBP, QWORD[USINI+(CW*(3))] ;Return stack ... LODSD ; NEXT JMP QWORD[RAX] 以NASM 64位指定此指令的正确方式是什么? 当然,这可能是nasm的一个缺陷,但我如何才能确定这一点呢 (在fa

我在一个32位程序(一个Forth解释器)中有以下nasm代码

最后一条指令获取AX指向的地址并跳到该地址。 64位的等效代码不再汇编:

    MOV     RBP, QWORD[USINI+(CW*(3))]    ;Return stack
    ...
    LODSD                  ; NEXT
    JMP      QWORD[RAX]
以NASM 64位指定此指令的正确方式是什么? 当然,这可能是nasm的一个缺陷,但我如何才能确定这一点呢

(在fasm中,完全相同的代码汇编效果良好。)

(第一个QWORD被nasm接受)

消息是:“ci86.lina64.asm:318:错误:地址大小不可能组合”
318与JMP一致

nasm版本为:2012年6月14日编译的nasm版本2.10.01

省略“QWORD”会显示相同的错误信息,此外: “ci86.lina64.asm:318:错误:地址大小不可能组合”

正如Jester指出的那样

jmp [rax]
是正确的,而

jmp qword[rax]
是允许的。 如果失败了,你就做错了别的事情

在这种情况下,问题在于缺少

第64位

关键词

为了获得一个64位的对象文件,您需要在调用nasm的命令行中指定-felf64作为体系结构,如下所示

nasm x.asm-felf64-g-o x.o

在这种情况下,位64是隐含的。当然,问题是,你永远无法通过装配,也无法发现错误

正如杰斯特指出的那样

jmp [rax]
是正确的,而

jmp qword[rax]
是允许的。 如果失败了,你就做错了别的事情

在这种情况下,问题在于缺少

第64位

关键词

为了获得一个64位的对象文件,您需要在调用nasm的命令行中指定-felf64作为体系结构,如下所示

nasm x.asm-felf64-g-o x.o


在这种情况下,位64是隐含的。当然,问题是,你永远无法通过装配,也无法发现错误

首先,
jmp[mem]
是一个内存间接跳转(set RIP=从内存加载的指针)
jmp-rax
将是一个寄存器间接跳转,设置为
RIP=rax

你没说哪条线是318号线。你确定这是
jmp
?因为这一行的语法看起来没有什么问题

您的代码还在64位模式下使用32位指针吗?这是可能的,只要您坚持低4GB的地址空间,使地址适合32b。改变这一点需要重新调整存储指针的所有数据结构的大小

请注意,默认情况下堆栈地址不在低位32b。使用32位地址大小前缀(例如,
mov-rdx[eax]
)符号扩展地址

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个UOP,因此如果您确实需要这两种效果,它们实际上不是一个坏选择。

首先,
jmp[mem]
是内存间接跳转(设置RIP=从内存加载的指针)
jmp-rax
将是一个寄存器间接跳转,设置为
RIP=rax

你没说哪条线是318号线。你确定这是
jmp
?因为这一行的语法看起来没有什么问题

您的代码还在64位模式下使用32位指针吗?这是可能的,只要您坚持低4GB的地址空间,使地址适合32b。改变这一点需要重新调整存储指针的所有数据结构的大小

请注意,默认情况下堆栈地址不在低位32b。使用32位地址大小前缀(例如,
mov-rdx[eax]
)符号扩展地址

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个UOP,因此如果您确实需要这两种效果,它们实际上不是一个坏选择。

jmp[rax]
是一个64位跳转,因为所有间接跳转都是64位的。您不需要
qword
,即使它确实有效。不过,还不清楚您是想
jmprax
还是
jmp[rax]
。你还忘了发布nasm版本和你得到的错误。我只会在尝试以32位的形式组装时得到这个错误。你确定你正确使用了64位吗?没错,杰斯特。我忘了从“第64位”开始。所有这些QWORDS都被接受了,我完全无法朝着这个方向思考。投票以“印刷错误”结束,如果只是这样的话。这是一个棘手的问题,花了我很多时间。将其视为单纯的印刷错误会使人们无法了解省略位64关键字会导致何种情况。
jmp[rax]
是一种64位跳转,因为所有间接跳转都是64位的。您不需要
qword
,即使它确实有效。不过,还不清楚您是想
jmprax
还是
jmp[rax]
。你还忘了发布nasm版本和你得到的错误。我只会在尝试以32位的形式组装时得到这个错误。你确定你正确使用了64位吗?没错,杰斯特。我忘了从“第64位”开始。所有这些QWORDS都被接受了,我完全无法朝着这个方向思考。投票以“印刷错误”结束,如果只是这样的话。这是一个棘手的问题,花了我很多时间。将其视为单纯的印刷错误会使人们无法了解省略BITS 64关键字会导致什么样的情况。当然,代码是按预期编写的。这是一个成熟的Forth解释器(2001年,自2008年以来为64位),有几十个程序解决了projecteuler.net问题,有时运行几天。@AlbertvanderHorst:所以你不把它移植到64位?从问题的措辞来看,我认为你是。您是否在为自己的项目借用它的代码块?我不明白是什么改变使它“停止工作”。我有一个系统,通过m4可以为d生成相同的汇编代码