计算机工作原理
1.冯诺依曼体系结构
五大组件:运算器、存储器、控制器、输入与输出设备核心思想:存储程序;
计算机内部采用二进制来表示指令和数据。
2.汇编基础
CPU通用寄存器
数据寄存器AX:累加寄存器
BX:基地址寄存器
CX:计数器寄存器
DX:数据寄存器
指针寄存器
SP:堆栈指针寄存器
BP:基指针寄存器
变址寄存器
SI:源变址寄存器
DI:目的变址寄存器
其他寄存器
标志寄存器、指令寄存器、段寄存器寄存器位数分辨
E:32位;R:64位;在定位一个指令时,使用CS:EIP来准确指明他的地址。
寻址方式
三种操作数
立即数: 常数,符号$加数值;寄存器数: 寄存器中保存的值,%eax;对字节操作是对八个单字节寄存器的一个,%al;
寄存器引用:经过计算的有效地址访问;
寻址方式
寄存器寻址:movl %eax,%eax; edx=edx;立即寻址:movl $0x123,%eax; edx=0xedx;
直接寻址:movl 0x123,%eax edx=*(int*)0xedx;
间接寻址:movl (%eax),%eax; edx=*(int*)edx
变址寻址:movl 4(%eax),%eax; edx=*(int*)(edx+4)
常用指令
pushl: 压栈 指令:pushl %eax;执行步骤1.subl $4, %esp;
执行步骤2.movl %eax,(%eap);
popl:出栈 指令:popl %eax;
执行步骤1.movl (%esp),%eax;
执行步骤2.addl $4, %esp;
call:函数调用 指令:call 0x12345;
pushl %eip
movl $0x123245, %eip
两个动作一次完成
ret:函数返回 指令:ret;
popl %eip
实验
编译过程:预处理 编译 汇编 链接1 int g(int x) 2 { 3 return x + 5; 4 } 5 int f(int x) 6 { 7 return g(x); 8 } 9 int main(void) 10 { 11 return f(8) + 1; 12 }
main.c文件中内容。经gcc -S -o main.s main.c -m32将其转化为汇编语言。
1 .file "main.c" 2 .text 3 .globl g 4 .type g, @function 5 g: 6 .LFB0: 7 .cfi_startproc 8 pushl %ebp 9 .cfi_def_cfa_offset 8 10 .cfi_offset 5, -8 11 movl %esp, %ebp 12 .cfi_def_cfa_register 5 13 movl 8(%ebp), %eax 14 addl $5, %eax 15 popl %ebp 16 .cfi_restore 5 17 .cfi_def_cfa 4, 4 18 ret 19 .cfi_endproc 20 .LFE0: 21 .size g, .-g 22 .globl f 23 .type f, @function 24 f: 25 .LFB1: 26 .cfi_startproc 27 pushl %ebp 28 .cfi_def_cfa_offset 8 29 .cfi_offset 5, -8 30 movl %esp, %ebp 31 .cfi_def_cfa_register 5 32 subl $4, %esp 33 movl 8(%ebp), %eax 34 movl %eax, (%esp) 35 call g 36 leave 37 .cfi_restore 5 38 .cfi_def_cfa 4, 4 39 ret 40 .cfi_endproc 41 .LFE1: 42 .size f, .-f 43 .globl main 44 .type main, @function 45 main: 46 .LFB2: 47 .cfi_startproc 48 pushl %ebp 49 .cfi_def_cfa_offset 8 50 .cfi_offset 5, -8 51 movl %esp, %ebp 52 .cfi_def_cfa_register 5 53 subl $4, %esp 54 movl $8, (%esp) 55 call f 56 addl $1, %eax 57 leave 58 .cfi_restore 5 59 .cfi_def_cfa 4, 4 60 ret 61 .cfi_endproc 62 .LFE2: 63 .size main, .-main 64 .ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2" 65 .section .note.GNU-stack,"",@progbits
上述为main.s中内容。
gcc中常用选项: 1. -o <FILE> 指定输出的文件,如果是一个文件的C程序不指定-o选项,则输出的文件是一个a.out的可执行文件,运行。./a.out运行
2. -c 只编译不连接,通知GCC取消链接步骤,即编译源码并在最后生成目标文件
3. -I 指定include搜索的路径。
4. -L 指定库的搜索路径。
5. -l 指定所用到的库。
6. -g 加入调试信息。
7. -o与-g不能联用。
2. -c 只编译不连接,通知GCC取消链接步骤,即编译源码并在最后生成目标文件
3. -I 指定include搜索的路径。
4. -L 指定库的搜索路径。
5. -l 指定所用到的库。
6. -g 加入调试信息。
7. -o与-g不能联用。