1

The MOV have the two form to move an imm to 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. |
    

In the example bellow, Line 6(Line 5,7 are not so important, we ignore it.) use the 2nd form. So the problem is, if we link the object file with '-Ttext=' to specify a address that can be fit in 32bits, e.g. 'ld m.o -Ttext=0x1234' it works well. but if we use an addres wider than 32bits, e.g. 'ld m.o -Ttext=0x1234567887', it does not works.

If Line 6 is encoded in the 1st form, i think the two link command above will both work well.

So how to direct the gas encode the Line 6 in the 1st form?

 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'
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
yang wen
  • 427
  • 4
  • 15
  • You can force a 64-bit absolute immediate with `movabs`, but you almost never want that. Use RIP-relative LEA unless you need a "large"/"huge" code-model where the label address might be more than +-2GiB away from the instruction that uses the address. Ultimately a duplicate of [How to load address of function or label into register](https://stackoverflow.com/q/57212012) and/or [Difference between movq and movabsq in x86-64](https://stackoverflow.com/q/40315803) – Peter Cordes Jan 14 '23 at 03:53

1 Answers1

-2

I got it. I write a funciton like

long aaa(void)
{
    return 0x1234567890l;
}

and the gcc generate following asm code

movabsq $78187493520, %rax

to return the value. My example works in this way now.

Posted on behalf of the question asker

Dharman
  • 30,962
  • 25
  • 85
  • 135
  • 1
    In this case with the string (data) in the code section, another option is to use RIP relative addressing since the data is within range of 32-bit relative offset. So this should work as well `lea str(%rip), %rsi` – Michael Petch Jan 14 '23 at 01:40