本文已参与「新人创作礼」活动,一起开启掘金创作之路。
这篇文章介绍指令的相关操作。
指令操作
首先看看处理器是如何配合内存进行计算的:
- 程序计数器(PC, Program counter) - 存着下一条指令的地址,在 x86-64 中称为 RIP
- 寄存器(Register) - 用来存储数据以便操作
- 条件代码(Codition codes) - 通常保存最近的算术或逻辑操作的信息,如
进位,也可以用来做条件跳转
汇编代码有固定的指令:
比如这样的形式: movq %rax, (%rbx)
指令语法
Windows用的是Intel格式的汇编 Linux用的是AT&T格式的汇编。
所以之前看到别人在讨论,其实他们都是对的,只是使用的机器不同罢了:
- 在本门课,默认格式是这样的:操作指令:源:目的
指令寻址
指令寻址分两种情况:
- 普通模式,(R),相当于 Mem[Reg[R]],也就是说寄存器 R 指定内存地址,类似于 C 语言中的指针,语法为:movq (%rcx), %rax 也就是说以 %rcx 寄存器中存储的地址去内存里找对应的数据,存到寄存器 %rax 中
- 移位模式,D(R),相当于 Mem[Reg[R]+D],寄存器 R 给出起始的内存地址,然后 D 是偏移量,语法为:movq 8(%rbp),%rdx 也就是说以 %rbp 寄存器中存储的地址再加上 8 个偏移量去内存里找对应的数据,存到寄存器 %rdx 中
- 完全寻址:D(Rb, Ri, S) -> Mem[Reg[Rb]+S*Reg[Ri]+D],S为系数
lea指令
lea是比较特殊的指令,但也类似于mov指令
因为lea指令将有效地址写入到目的操作数,也就是说:lea的作用是直接操作地址,没有引用内存
- 他的第一个操作数看上去是一个内存引用,但该指令并不是从指定的位置读入数据,而是将有效地址写入到目的操作数
- 他的第二个操作数必须是一个寄存器
主要用法是计算栈顶指针偏移量,leaq 8(%rsp), %rsi 就是把栈顶指针加上 8 得到一个新地址值,然后把这个地址值存到寄存器 %rsi 中