Skip to content

程序结构和执行

838字约3分钟

2024-11-02

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 被调用者保存 ... r15 被调用者保存

mov 指令 MOV S D S->D 传送 源操作数是一个立即数,存储寄存器或内存中 目的操作数是一个"地址",也就是这个位置。它可以是寄存器或是内存地址 目的操作数指定为立即数时需要 movabsq指令 如 movabsq $0x0011223344556677 ,%rax %rax =0x0011223344556677 指令需要指明移动寄存器的部分大小(b,w,l,q) movl以寄存器为目的寄存器时会把寄存器的高四位设置为0

较小的原值移动到较大的目的地址 MOVS 以0填充高位 MOVZ 以符号位填充高位

cltq S R 符号位扩展%eax -> %rax

exampl movabsq$0x0011223344556677 ,%rax %rax =0x0011223344556677 movb $0xAA ,%dl %dl=AA 将立即数移动到寄存器rdx最低八位也就是dl movb %dl,%al %rax=0x00112233445566AA 将寄存器rdx的低八位%dl中的值移动到%al寄存器中 movsbq %dl ,%rax %rax=FFFFFFFFFFFFFFAA 跟据原字节最高位设置扩展 movzbq %dl,%rax %rax=00000000000000AA 零扩展

示例

long exchange (long *xo,long y){
    long x=*xp;
    *xp=y;
    return x;
}
long exchange(long *xp,long y) xp int %rdi,y in %rsi
1 exchange:  
2 moveq (%rdi),%rax   取%rdi地址指向的内存空间的值传送给%rax。xp是指针,指针的值在寄存器中,那么解引用指针得出指针指向的值,这个"解引用"的操作映射为(%rdi)
3 movq %rsi,(%rdi)   作为对比这里不加括号,因为值就存储在%rsi寄存器中,取%rsi寄存器存储的值,移动到%rdi寄存器值所指向的内存中。
4 ret

pushq S 栈指针减少8(指针大小) 将四字压入栈 因为栈是倒过来画的地址由高到低 等价于 subq $8 ,%rsp movq %rbq,(%rsp) popq D 栈指针加8 将四字弹出 等价于 movq (%rsp),%rax addq $8,%rsp

算数操作 leaq S, D D <-&S 把S的地址传送给D INC D D <-D+1 加1 DEC D D <-D-1 减1 NEG 取负 NOR 取补 ADD 加 SUB S,D D<-D+S 减 IMUL 乘
XOR 异或 OR 或 AND 与 SAL S,D D <-D<<k 左移 SHL 左移同上 SAR 算数右移 SHR 逻辑右移

leaq 指令 load effective address 是movq指令的变形,他将有效地址写入到目的操作数,是从内存读数据到寄存器 如 设 %rdx中值为x leaq 7(%rdx,%rdx,4),%rax 将%rax中的值设置为5x+7 例

long 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=*xp; long zp1=*zp; *yp=xp1; *zp=yp1; *xp=zp1;

3.6