程序结构和执行
约 837 字大约 3 分钟
2024-11-02
AT&T汇编
AT&T汇编语法
指令 源操作数 目的操作数
描述内存中的位置:
- Intel:
QWORD PTR[rbx] - AT&T:
(%rbx)
数据大小
| 位数 | 名称 | 缩写 |
|---|---|---|
| 16位 | 字 | WORD |
| 32位 | 双字 | DWORD |
| 64位 | 四字 | QWORD |
通用寄存器
x86-64 提供了16个通用寄存器:
| 寄存器 | 用途 | 备注 |
|---|---|---|
| rax | 返回值 | eax, ax, al |
| rbx | 被调用者保存 | |
| rcx | 第四个参数 | |
| rdx | 第三个参数 | |
| rsi | 第二个参数 | esi, si, sil |
| rdi | 第一个参数 | |
| rbp | 栈底指针 | |
| r8 | 第五个参数 | r8d, r8w, r8b |
| r9 | 第六个参数 | |
| r10 | 被调用者保存 | |
| r11 | 被调用者保存 | |
| r12 | 被调用者保存 | |
| r13 | 被调用者保存 | |
| r14 | 被调用者保存 | |
| r15 | 被调用者保存 |
mov 指令
MOV指令格式
MOV S D — 将源操作数S传送到目的操作数D
- 源操作数:立即数、寄存器或内存
- 目的操作数:寄存器或内存地址
- 目的操作数不能是立即数
movabsq指令用于移动64位立即数:
movabsq $0x0011223344556677, %rax
# %rax = 0x0011223344556677注意
指令需要指明移动寄存器的部分大小(b,w,l,q)。movl以寄存器为目的寄存器时会把寄存器的高四位设置为0。
数据扩展
| 指令 | 说明 |
|---|---|
| MOVS | 以0填充高位 |
| MOVZ | 以符号位填充高位 |
cltq 指令:符号位扩展 %eax -> %rax
示例
long exchange(long *xp, long y) {
long x = *xp;
*xp = y;
return x;
}# long exchange(long *xp, long y)
# xp in %rdi, y in %rsi
exchange:
movq (%rdi), %rax # 取%rdi地址指向的内存空间的值传送给%rax
movq %rsi, (%rdi) # 将%rsi寄存器存储的值移动到%rdi寄存器值所指向的内存中
ret栈操作
push和pop指令
pushq S:栈指针减少8(指针大小),将四字压入栈
等价于:
subq $8, %rsp
movq %rbx, (%rsp)popq D:栈指针加8,将四字弹出
等价于:
movq (%rsp), %rax
addq $8, %rsp算术操作
| 指令 | 格式 | 说明 |
|---|---|---|
| leaq | leaq S, D | D <- &S,把S的地址传送给D |
| INC | INC D | D <- D+1,加1 |
| DEC | DEC D | D <- D-1,减1 |
| NEG | NEG D | 取负 |
| NOT | NOT D | 取补 |
| ADD | ADD S, D | D <- D+S,加 |
| SUB | SUB S, D | D <- D-S,减 |
| IMUL | IMUL S, D | D <- D*S,乘 |
| XOR | XOR S, D | 异或 |
| OR | OR S, D | 或 |
| AND | AND S, D | 与 |
| SAL | SAL S, D | D <- D<<k,左移 |
| SHL | SHL S, D | 左移(同SAL) |
| SAR | SAR S, D | 算术右移 |
| SHR | SHR S, D | 逻辑右移 |
leaq 指令
leaq(Load Effective Address)是movq指令的变形,它将有效地址写入到目的操作数,是从内存读数据到寄存器。
示例:设%rdx中值为x
leaq 7(%rdx,%rdx,4), %rax
# 将%rax中的值设置为5x+7long scale(long x, long y, long z) {
long t = x + 4*y + 12*z;
}3.9.1 例题
例题3.46
3.1 寻址模式
| 表达式 | 值 | 说明 |
|---|---|---|
| %rax | 0x100 | 寄存器 |
| 0x104 | 0xAB | 内存地址 |
| $0x108 | 0x108 | 立即数 |
| (%rax) | 0xFF | 间接寻址 |
| 4(%rax) | 0x103 | 基址+偏移 |
| 9(%rcx,%rdx) | 0x10c | 基址+变址+偏移 |
| 260(%rcx,%rdx) | 0x108 | 基址+变址+偏移 |
| 0xFC(,%rcx,4) | 0x101 | 变址寻址 |
| (%rax,%rdx,4) | 0x118 | 变址寻址 |
3.5 函数调用
函数原型:void decode1(long *xp, long *yp, long *zp)
参数传递:
- xp in %rdi
- yp in %rsi
- zp in %rdx
long xp1 = *xp;
long yp1 = *yp;
long zp1 = *zp;
*yp = xp1;
*zp = yp1;
*xp = zp1;