程序编码
汇编代码
- 汇编代码是人类可读的机器代码。
- 机器代码是一堆字节序列,它是对一系列指令的编码。
- 对下列代码使用 gcc -Og -o prog main.c mstore.c 生成可执行文件。使用gcc -Og -S mstore.c 可以生成汇编文件。
```c
include
void multstore(long, long, long *);
int main(){ long d; multstore(2,3,&d); printf(“2 * 3 —-> %ld\n”,d); return 0; }
long mult2(long a, long b){ long s = a*b; return s; }
```c
#include <stdio.h>
#include <string.h>
long mult2(long, long);
void multstore(long x, long y, long *dest){
long t = mult2(x,y);
*dest = t;
}
对prog 可执行文件使用objdump反汇编器,可以找到机器代码和汇编代码的对应关系
寄存器与数据传送指令
寄存器
每个寄存器都有自己特殊的功能,早期的寄存器是16位的,随着处理器架构的发展,一直升级到现在的64位寄存器。
-
指令
指令可以分解为:操作码 操作数。
操作码 操作数
pushq %rbp
movq %rsp, %rbp
pushq %rbx
pushq %rax
movq %rdx, %rbx
callq _mult2
movq %rax, (%rbx)
addq $8, %rsp
popq %rbx
popq %rbp
retq
操作数可以是一个立即数,寄存器,或者内存引用。以‘$’开头的代码是一个立即数,用来表示一个参数。寄存器表示某个寄存器里面的内容,比如%rbp,%rsp。内存引用表示某个计算出来的地址,比如(%rbx)。
内存引用的地址计算方法:
=
MOV指令由一个源操作数和一个目的操作数构成,MOV指令负责将数据从一个位置复制到另一个位置。
- 源操作数:可以是立即数,寄存器,或者内存引用。
- 目的操作数:只能是寄存器或者内存引用。
```c
movq %rsp, %rbp pushq %rbx pushq %rax movq %rdx, %rbx源操作数 目的操作数
<a name="j3aiz"></a>
## 压入和弹出数据栈
- **pushq S/popq D** 可以实现数据的压入和弹出。
- pushq %rbp 等价于
```c
subq %8, %rsp//先减去8个字节,0x108变更为0x100
movq %rbp,(%rsp)//把数据压入到0x100的位置