1

MOV 有两种形式将 imm 移动到 r64:

| Opcode         | Instruction     | Op/En | 64-Bit Mode | Compat/Leg Mode | Description                                   |
| REX.W + B8+ rd | MOV r64, imm64  | E     | Valid       | N.E.            | Move imm64 to r64.                            |
| REX.W + C7 /0  | MOV r/m64,imm32 | F     | Valid       | N.E.            | Move imm32 sign extended to 64-bits to r/m64. |

在下面的示例中,第 6 行(第 5,7 行不是那么重要,我们忽略它。)使用第二种形式。所以问题是,如果我们用'-Ttext=' 链接目标文件来指定一个适合32 位的地址,例如'ld mo -Ttext=0x1234' 它工作得很好。但是如果我们使用一个超过 32 位的地址,例如 'ld mo -Ttext=0x1234567887',它就不起作用。

如果第 6 行以第一种形式编码,我认为上面的两个链接命令都可以正常工作。

那么如何引导气体以第一种形式对第 6 行进行编码呢?

 1
 2  .code64
 3  .global _start
 4  _start:
 5      movq $1, %rdi
 6      movq $str, %rsi
 7      movq $len, %rdx
 8      movl $1, %eax
 9      syscall
10      movq $0, %rdi
11      movl $60, %eax
12      syscall
13  str: .asciz "hello write\n"
14  .equ len, . - str

# as m.s -o m.o
# ld m.o -Ttext=0x1234

0000000000001234 <_start>:
1234:       48 c7 c7 01 00 00 00    mov    $0x1,%rdi
123b:       48 c7 c6 5e 12 00 00    mov    $0x125e,%rsi
1242:       48 c7 c2 0d 00 00 00    mov    $0xd,%rdx
1249:       b8 01 00 00 00          mov    $0x1,%eax
124e:       0f 05                   syscall
1250:       48 c7 c7 00 00 00 00    mov    $0x0,%rdi
1257:       b8 3c 00 00 00          mov    $0x3c,%eax
125c:       0f 05                   syscall

# ld m.o -Ttext=0x1234567887
m.o: In function `_start':
(.text+0xa): relocation truncated to fit: R_X86_64_32S against `.text'

编辑:

我知道了。我写了一个类似的函数

long aaa(void)
{
    return 0x1234567890l;
}

和 gcc 生成以下 asm 代码

movabsq $78187493520, %rax

返回值。我的示例现在以这种方式工作。

但我在“ingo gas”中没有找到任何关于“movabsq”的内容。有人告诉我在哪里可以得到帮助?谢谢!

4

0 回答 0