You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

movq指令中40(%rdi)的40含义解析及GCC相关疑问

Understanding the 40 in movq 40(%rdi), %rax

Let's break this down clearly, since you've already noticed some interesting patterns in GCC's generated code!

What does the 40 mean?

In x86-64 assembly, the syntax disp(base) refers to a base + displacement memory addressing mode. Here's exactly what's happening:

  • %rdi holds a memory address (the "base" address)
  • The 40 is a fixed offset (displacement) that gets added to the base address in %rdi
  • movq 40(%rdi), %rax reads an 8-byte (quadword, hence q in movq) value from the memory address %rdi + 40, then stores that value into the %rax register.

The parentheses () are indeed how you indicate "dereference this address"—just like the * operator in C for pointers.

Why does GCC always use multiples of 8?

Great observation! This ties directly to data alignment in C (and most high-level languages targeting x86-64):

  • On x86-64 systems, the default alignment rule for 64-bit types (like pointers, long long, double, or struct members that are 64-bit) is 8 bytes. This means these types are always stored at memory addresses that are multiples of 8.
  • When GCC generates code to access struct members, array elements, or other 64-bit values, it calculates their offset from the base pointer (%rdi might be pointing to a struct instance, for example) as a multiple of 8 to maintain this alignment.
  • Aligned memory accesses are faster on x86-64 (the CPU can fetch the data in a single cycle), while unaligned accesses may require multiple cycles or even cause errors on some stricter architectures (though x86-64 allows them).

Why do non-multiples of 8 compile but give weird results?

x86-64 is lenient about unaligned memory access—your assembler won't throw an error because the architecture supports it. But here's why the results look like garbage:

  • movq always reads 8 full bytes from the target address. When you use a displacement that's not a multiple of 8 (like 1, 2, or 7), you're starting the 8-byte read at an unaligned address.
  • For example, if you write movq $1, (%rdi), you're storing the 8-byte value 0x0000000000000001 at %rdi. When you read 1(%rdi), you're fetching 8 bytes starting at %rdi + 1: this includes the last 7 bytes of the 0x0000000000000001 (which are all 0) plus the first byte of whatever random data is stored at %rdi + 8. The combination of these bytes gives you that huge, nonsensical number in %rax.
  • Unaligned reads like this rarely make sense in real code—they're either accidental or used in very specific low-level scenarios (like parsing packed binary data).

内容的提问来源于stack exchange,提问作者sviamwvnb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:36:16