gpt4 book ai didi

assembly - 在 x86-64 中指定 8 位立即数(GNU 汇编器)

转载 作者:行者123 更新时间:2023-12-02 22:01:25 31 4
gpt4 key购买 nike

我正在尝试在汇编中为 x86-64 编写一些特殊例程(即使 x86 示例也可以)。问题:我的立即数仅在链接时得到解决。

例如,

addq $Label2-Label1, %rax

会将两个标签/符号之间的差异添加到 rax。不幸的是,因为 GNU 汇编器只执行一次传递(我不知道为什么,即使像 FASM 这样的开源汇编器也会执行多次传递),它无法解析这些,因此它将让链接器执行此操作。

不幸的是,它会为链接器保留4个字节(32位立即数),这不是我想要的,因为标签的差异总是在-128到+127范围内。

我的问题是,如何强制或指定指令应具有 8 位立即数?比如,这里的语法是什么?在 AT&T 语法或 Intel 语法中,两者都可以。例如,在 NASM 中,您可以:

add rax, byte Label2-Label1

指定8位立即数。但如何在 GAS 中做到这一点呢?即使它不知道立即数本身,强制它使用 8 位立即数的语法是什么...出于特定原因,我理想地希望在 GAS 中使用它,所以请不要告诉我使用 NASM 作为回答!

编辑:很抱歉我忘了提及,是的,这里是“前向引用”。两个标签都是在指令之后定义的,这就是为什么 GAS 无法解析它们,我认为这是一个重定位,但是使用 '.byte label2-label1' 确实有效,因为我已经测试过它,所以我知道它应该是可能的如果它有一些语法......

最佳答案

如果Label1Label2位于同一个源文件中,那么问题似乎与链接器无关(GAS不会在该文件中生成任何重定位)情况)也不是因为 GAS 是一次性汇编器。它足够智能,可以生成正确大小的分支,这是一个类似的问题。

问题归结为 GAS 不够聪明,无法在跳转和分支之外的情况下选择正确大小的指令,并且没有任何方法来显式指定操作数的大小。 “.d8”位移后缀几乎是您想要的语法,但从技术上讲您并没有使用位移。但无论如何它都不起作用,因为 leal.d8 Label2-Label1(%eax),%eax 不起作用,尽管实际上正在使用位移。

因此,实际上只剩下一种选择,即手动组装操作码。例如在 32 位汇编中:

.byte 0x83, 0xC0, (label2 - label1)

至于为什么 GAS 只是一个一次性汇编器,并且通常不做其他汇编器的许多事情,答案很简单。它主要设计用于组装 GCC 的输出。

关于assembly - 在 x86-64 中指定 8 位立即数(GNU 汇编器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25411652/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com