x86-64 Memory Architecture and mov Instructions: Deep Dive into Addressing Mechanisms, Stack Operati

x86-64 Memory Architecture and mov Instructions: Deep Dive into Addressing Mechanisms, Stack Operati

本文为纯手打原创硬核干货,适合学习计算机组成汇编CSAPP 的同学,欢迎真实阅读、交流。


Based on the x86-64 architecture, this article starts with the matrix-based physical implementation of main memory, systematically breaks down the memory addressing mechanism, the family of data transfer instructions, and the logic of stack operations. It will help you fully grasp the underlying principles of CPU-memory interaction and thoroughly understand the essence of the mov instruction.


I. Physical Implementation of Main Memory and Addressing

1.1 Matrix-Based Storage Structure

Modern main memory is implemented using a matrix structure, rather than a simple linear arrangement. The core motivation behind this design is to avoid the physical wiring challenges caused by “extremely long memory address lines.”

Core Idea: Map a one-dimensional address into a two-dimensional physical space through row and column decoding, significantly reducing the complexity of address decoding circuits.

1.2 Memory Model in x86-64

In the x86-64 architecture, the memory system has the following key characteristics:

FeatureDescription
Address SpaceTheoretically supports 2642^{64}264 distinct memory addresses
Address LengthEach memory address requires 64 bits in binary representation
Addressing GranularityEach address points to a single byte (1 byte = 8 bits)
Byte OrderLittle-Endian
Although the architecture supports a 2642^{64}264 address space, actual implementations typically use only 48 bits (256 TB) to avoid excessively large page tables.

II. Data Formats and mov Instruction Rules

x86-64 Data Types

x86-64 assembly instructions use a single-character suffix to explicitly indicate the operand size. This is fundamental to understanding instruction behavior:

SuffixFull NameSizeExample Instruction
bbyte1 byte (8 bits)movb
wword2 bytes (16 bits)movw
llong/double word4 bytes (32 bits)movl
qquad word8 bytes (64 bits)movq

2.1 Data Movement Instructions (mov)

InstructionEffect
movbmove byte
movwmove word
movlmove double word
movqmove quad word
InstructionEffect
movbmove byte
movwmove word

2.2 Special Transfer Instruction: movabsq

When handling 64-bit immediate values, the standard movq may cause truncation (sign extension). In such cases, movabsq must be used:

; Incorrect: immediate is truncated to 32 bits and then sign-extended movq $0x0011223344556677, %rax ; %rax = 0x0000000044556677 ❌ ; Correct: full 64-bit immediate transfer movabsq $0x0011223344556677, %rax ; %rax = 0x0011223344556677 ✓ 

III. x86-64 Register System

3.1 Hierarchical Structure of General-Purpose Registers

x86-64 registers support partial access, which is a key design for backward compatibility with 32/16/8-bit code:

Common x86-64 Registers

Data Consistency of Registers:
As shown above, these registers of different sizes are physically nested accesses to the same underlying storage unit.

This means registers of the same type completely share their contents:

  • Write synchronization: Writing to a lower-sized register (such as %eax) will also affect the corresponding 64-bit register (%rax).
  • Partial read: No matter which size alias you operate on, you are accessing the same data. If you write a 64-bit integer into %rax, you can later read its lower 32 bits through %eax or its lowest byte through %al.
In the x86-64 specification, writing to a 32-bit register (such as %eax) will automatically zero the upper 32 bits.

3.2 Common Registers Overview

64-bit32-bit16-bit8-bitUsage
%rax%eax%ax%alAccumulator, return value
%rbx%ebx%bx%blBase register
%rcx%ecx%cx%clCounter, loop variable
%rdx%edx%dx%dlData register
%rsi%esi%si%silSource index
%rdi%edi%di%dilDestination index
%r8-%r15%r8d-%r15d%r8w-%r15w%r8b-%r15bExtended registers

In functions, %rdi generally represents the first argument, %rsi the second argument, and %rcx often corresponds to the C-language index “i”.
Note that these are 64-bit registers corresponding to the long type. If the parameter type is different, the corresponding register variant must be used. For example, if the parameter is int, use %edi and %esi.


IV. Operand Addressing Modes

x86-64 provides flexible addressing methods, which can be divided into three categories: Immediate, Register, and Memory.
Memory refers to the value stored at the address contained in a register, which may be a value or another address.

4.1 Addressing Mode Quick Reference

TypeFormOperand ValueName
Immediate$ImmImmImmImmImmediate
RegisterraR[ra]R[ra]R[ra]Register
AbsoluteImmM[Imm]M[Imm]M[Imm]Absolute
Indirect(ra)M[R[ra]]M[R[ra]]M[R[ra]]Indirect
Base + displacementImm(rb)M[Imm+R[rb]]M[Imm + R[rb]]M[Imm+R[rb]]Base + displacement
Indexed(rb, ri)M[R[rb]+R[ri]]M[R[rb] + R[ri]]M[R[rb]+R[ri]]Indexed
Scaled indexed(rb, ri, s)M[R[rb]+R[ri]⋅s]M[R[rb] + R[ri] \cdot s]M[R[rb]+R[ri]s]Scaled indexed
📝 Scale factor s: can only be 1, 2, 4, 8 (convenient for array element access)

4.2 Address Calculation Example

Assume the following register and memory state:

AddressValueRegisterValue
0x1000xFF%rax0x100
0x1040xAB%rcx0x1
0x1080x13%rdx0x3
0x10C0x11--

Then the operand values are:

OperandCalculationResult
%raxR[%rax]0x100
0x104M[0x104]0xAB
$0x1080x1080x108
(%rax)M[0x100]0xFF
4(%rax)M[0x100 + 4]0xAB
9(%rax, %rdx)M[0x100 + 0x3 + 9]0x11
260(%rcx, %rdx)M[0x1 + 0x3 + 0x104]0x13
(%rax, %rdx, 4)M[0x100 + 0x3 * 4]0x11
  • Common scenario: %rdi is the array A in parameters, %rcx represents offset i
    • Registers and addressing logic
      %rdi = A (array base address/pointer)
      %rcx = i (index/offset)
    • Addressing mapping for different data types
      int *A: (%rdi, %rcx, 4) -> A[i]
      char *A: (%rdi, %rcx, 1) -> A[i]
      long *A: (%rdi, %rcx, 8) -> A[i]

V. Data Extension Transfer Instructions

5.1 Zero Extension

Extend smaller data to larger data, filling high bits with zero:

InstructionSourceDestinationEffect
movzbw8-bit16-bitzero-extend to word
movzbl8-bit32-bitzero-extend to double word
movzbq8-bit64-bitzero-extend to quad word
movzwl16-bit32-bitzero-extend to double word
movzwq16-bit64-bitzero-extend to quad word
  • Special equivalence: movzlq %ecx, %rax is equivalent to movl %ecx, %eax, because a 32-bit move automatically zero-extends to 64 bits.

5.2 Sign Extension

Extend smaller data to larger data, copying the sign bit into higher bits:

InstructionSourceDestination
movsbw8-bit16-bit
movsbl8-bit32-bit
movsbq8-bit64-bit
movswl16-bit32-bit
movswq16-bit64-bit
movslq32-bit64-bit
cltq%eax%rax(abbreviation of movslq %eax, %rax)
  • cltq = movslq %eax, %rax => %rax = sign-extend(%eax)

5.3 Extension Instruction Comparison Experiment

movq $0x0011223344556677, %rax ; %rax = $0x0000000044556677 (only low 8 bytes modified) movabsq $0x0011223344556677, %rax ; %rax = 0x0011223344556677 movb $0xAA, %dl ; %dl = 0xAA (10101010) movb %dl, %al ; %rax = 0x00112233445566AA (only lowest byte modified) movsbq %dl, %rax ; %rax = 0xFFFFFFFFFFFFFFAA (sign-extended, 1-filled) movzbq %dl, %rax ; %rax = 0x00000000000000AA (zero-extended, 0-filled) 

VI. Stack Operations: Push and Pop

In the x86-64 architecture, the stack is not merely a data structure; it is a hardware-encoded memory region maintained by the %rsp register. Its core logic lies in the reverse growth of addresses synchronized with pointer dereferencing.

6.1 Core Concept: Counterintuitive “Downward Growth”

The stack is a special region of memory used for temporarily storing data (such as local variables and saved register states).

  • Stack pointer: The %rsp register always stores the starting address of the current top element of the stack.
  • Downward growth: A push operation causes %rsp to move toward lower addresses. In other words, as more data is pushed, the numerical value in %rsp becomes smaller.
  • Operation unit: In x86-64 systems, the standard stack operation unit is a Quadword (8 bytes / 64 bits).

6.2 Instruction Decomposition: Micro-Operation Equivalence

push and pop are highly encapsulated instructions. Their execution flow can be decomposed into pointer arithmetic and memory access:

  • Push
    Executing pushq %rax causes the CPU to perform:
  1. Pointer decrement: subtract 8 from %rsp (move downward by 8 bytes to allocate space).
  2. Memory write: store the data in %rax into the new address pointed to by %rsp.
pushq %rax is fully equivalent to: subq $8, %rsp ; 1. stack pointer moves downward (address decreases) movq %rax, (%rsp) ; 2. write data to new top address 
  • Pop
    Executing popq %rax performs the reverse sequence:
  1. Memory read: copy the value pointed to by %rsp into %rax.
  2. Pointer increment: add 8 to %rsp (reclaim the 8-byte space).
popq %rax is fully equivalent to: movq (%rsp), %rax addq $8, %rsp 

6.3 State Trace: Register and Memory Instantaneous States

Below is a trace analysis assuming %rsp initially equals 0x8000:

Instruction%rax Value%rsp (Stack Top Address)Memory StateDescription
movq $0x123, %rax0x1230x8000M[0x8000] = ?Initialize register
pushq %rax0x1230x7FF8M[0x7FF8] = 0x123Pointer moves down 8 bytes and writes
movq $0x22, %rax0x220x7FF8M[0x7FF8] = 0x123Register overwritten, memory unchanged
pushq %rax0x220x7FF0M[0x7FF0] = 0x22Pointer moves down again and writes
popq %rax0x220x7FF8M[0x7FF8] = 0x123、M[0x7FF0] = 0x22Data loaded into register, pointer restored
Observe the last row popq %rax:
The pop operation only changes the %rsp pointer; it does not clear or erase old data in memory!
The 0x22 at address 0x7FF0 is not physically erased. Until overwritten by a future push, it is considered garbage data.

VII. Common Errors and Notes

7.1 Illegal Operand Combinations

Incorrect InstructionReasonCorrect Form
movb $0xF, (%ebx)Cannot use %ebx (32-bit) as address registermovb $0xF, (%rbx)
movl %rax, (%rsp)Suffix l does not match 64-bit register raxmovq %rax, (%rsp)
movw (%rax), 4(%rsp)Source and destination cannot both be memoryUse register as intermediary
movb %al, %sl%sl register does not existmovb %al, %sil
movq %rax, $0x123Immediate cannot be destination operandmovq $0x123, %rax
movl %eax, %dxDestination operand size incorrectmovl %eax, %edx
movb %si, 8(%rbp)Suffix b does not match 16-bit register simovw %si, 8(%rbp)

7.2 Key Principles

  1. mov is just a copy: No persistent link is established between source and destination; it is only a value copy.
  2. Memory-to-memory prohibited: x86-64 does not allow a single instruction to directly transfer data between two memory locations.
  3. Immediate constraints: Immediate values cannot be destination operands, and their size is limited by the instruction suffix.

VIII. Practice: C Code and Assembly Comparison

8.1 Swap Function

voidswap(long*xp,long*yp){long t0 =*xp;long t1 =*yp;*xp = t1;*yp = t0;}

Corresponding x86-64 assembly:

swap: movq (%rdi), %rax ; t0 = *xp (xp in %rdi) movq (%rsi), %rdx ; t1 = *yp (yp in %rsi) movq %rdx, (%rdi) ; *xp = t1 movq %rax, (%rsi) ; *yp = t0 ret 

Execution trace:

  • Initial: %rdi=0x120 (stores 123), %rsi=0x100 (stores 456)
  • After execution: 0x120 becomes 456, 0x100 becomes 123

8.2 Array Addressing

Assume long long array[8] base address is in %rdx and index 4 is in %rcx.
Goal: store array[4] into %rax

movq (%rdx, %rcx, 8), %rax # 1. Compute address %rdx + 4*8 # 2. Move 8 bytes from that memory address into %rax 

IX. Summary and Outlook

Starting from the matrix implementation of main memory, this article systematically reviewed the following aspects of the x86-64 architecture:

  1. Addressing system: 2642^{64}264 byte address space, byte-level addressing
  2. Data formats: b/w/l/q sizes with explicit instruction suffixes
  3. Register design: hierarchical partial access mechanism
  4. Flexible addressing: 9 memory addressing modes with scaled indexing
  5. Data extension: precise control of zero and sign extension
  6. Stack mechanism: push/pop operations growing toward lower addresses

Understanding these low-level mechanisms forms a solid foundation for subsequent study of arithmetic logic instructions, control flow, procedure calls, and memory hierarchy structures. Main memory is not only a container for data but also the core interface between the CPU and software. Mastering its working principles is essential to truly understanding the complete picture of computer systems.


References

  • “Computer Organization” course notes
  • Computer Systems: A Programmer’s Perspective (CS:APP), Chapter 3
  • Intel 64 and IA-32 Architectures Software Developer’s Manual

Last updated: 2026-02-26

Read more

【保姆级教程】从零入手:Python + Neo4j 构建你的第一个知识图谱

【保姆级教程】从零入手:Python + Neo4j 构建你的第一个知识图谱

摘要: 大数据时代,数据之间的关系往往比数据本身更有价值。传统的 SQL 数据库在处理复杂关系(如社交网络、推荐系统、风控分析)时显得力不从心,而 知识图谱 和 图数据库 Neo4j 正是为此而生。本文将带你从 0 基础出发,理解知识图谱核心概念,安装 Neo4j 环境,并手把手教你用 Python 代码构建一个生动的人物关系图谱。拒绝枯燥理论,全是实战干货! 一、 什么是知识图谱与 Neo4j? 在动手写代码之前,我们先用大白话把两个核心概念捋清楚。 1. 什么是知识图谱 (Knowledge Graph)? 不要被高大上的名字吓到。知识图谱本质上就是把世界上的事物(节点)和它们之间的联系(关系)画成一张巨大的网。 * Excel 思维: 罗列数据。例如:张三,25岁;李四,

AI绘画不求人:Z-Image Turbo本地部署全攻略,开箱即用

AI绘画不求人:Z-Image Turbo本地部署全攻略,开箱即用 你是不是也经历过这样的时刻:看到一张惊艳的AI插画,立刻打开浏览器搜教程,结果被“CUDA版本冲突”“PyTorch编译失败”“显存不足OOM”这些报错拦在门外?明明只是想画一幅水墨小景,却卡在环境配置第三步,连WebUI的界面都没见着。 别再折腾了。今天这篇不是教你“如何硬刚报错”,而是直接给你一条干净、稳定、真正能跑起来的本地部署路径——专为 Z-Image Turbo 量身定制的 Gradio + Diffusers 极速画板镜像,从下载到出图,全程无需改一行代码、不装一个依赖、不碰一次终端命令。它不是“理论上可行”的方案,而是我亲手在RTX 4060、RTX 3090、甚至16GB显存的MacBook Pro(M3 Max + Metal后端)上反复验证过的“开箱即用”方案。 更关键的是,它解决了国产AI绘画模型落地最头疼的三大痛点:黑图、

打造你的家庭 AI 助手(三):QQ 机器人接入你的 OpenClaw

打造你的家庭 AI 助手(三):QQ 机器人接入你的 OpenClaw

不得不承认腾讯进步的速度太快了,几条命令就可以接入Openclaw,也不用设置IP白名单了,在 QQ开放平台还增加了专门的Openclaw入口: 没啥好说的,很简单,安装完Openclaw之后,执行如下命令(命令也是生成好的): openclaw plugins install @tencent-connect/openclaw-qqbot@latest openclaw channels add--channel qqbot --token"" openclaw gateway restart 以下内容已经过时了,留作纪念 以下内容已经过时了,留作纪念 以下内容已经过时了,留作纪念 ⚠️ 重要提示:如果是家用宽带,没有申请固定 IP 地址的话,大可以放弃这种方式。由于 QQ 开发平台的白名单限制,机器人会非常不稳定,频繁掉线。建议使用云服务器或有固定 IP 的环境部署。 前言 在完成 OpenClaw 安装后,

龙虾机器人(OpenClaw)本地部署完全技术指南

龙虾机器人(OpenClaw)本地部署完全技术指南

龙虾机器人(OpenClaw)本地部署完全技术指南 前言:什么是“龙虾机器人”? 在开始部署之前,我们需要明确部署的对象。通常所说的“龙虾机器人”指的是开源项目 OpenClaw(曾用名:Clawdbot、Moltbot)。它由程序员彼得·斯坦伯格开发,是一个开源的、可本地部署的通用型AI代理系统。与ChatGPT等对话式AI不同,OpenClaw被赋予了操作系统的权限:它可以执行终端命令、读写文件、操控浏览器、安装软件,甚至通过MCP协议调用外部工具。 由于其强大的系统操控能力,安全性是部署时需关注的首要问题。官方及社区普遍建议:不要在主力机或存有敏感数据的生产环境直接裸奔部署,最好使用虚拟机、Docker容器或专用硬件(如Mac Mini或AI开发盒子)进行隔离。 第一章:环境准备与核心依赖 在安装OpenClaw之前,必须准备好运行环境。OpenClaw的核心由TypeScript编写,因此Node.js是必不可少的运行环境。此外,根据安装方式的不同,可能还需要Git、Docker或Python环境。 1.1 硬件建议与系统选择 * Linux