CSAPP杂记之程序的机器级表示

程序的机器级表示

程序编码

1.C预处理器扩展源代码,插入所有用#include命令指定的文件,并扩展所有用#define声明指定的宏
2.编译器产生源文件的汇编代码 .s文件
3.汇编器将汇编代码转化为二进制目标代码文件 .o文件
4.连接器将两个目标代码文件与实现库函数的代码合并,产生最终的可执行代码


机器级代码

名称 程序计数器(PC)
x86-64表示 %rip
含义 给出将要执行的下一条指令在内存中的地址

要查看机器代码文件的内容,可以用到反汇编器(disassembler)
反汇编器只是基于机器代码文件中的字节序列来确定汇编代码。

linux> objdump -d mstore.o

数据格式

C声明 Intel数据类型 汇编代码后缀 大小(字节)
char 字节 b 1
short w 2
int 双字 l 4
long 四字 q 8
char* 四字 q 8
float 单精度 s 4
double 双精度 l 8

访问信息

一个x86-64的CPU包含一组16个存储64位值的通用目的寄存器,用来存储整数数据和指针。

源操作数分为:

1.立即数
2.寄存器
3.内存引用


指针的一些示例

C语言中的“指针”其实就是地址。
间接引用指针就是将该指针放在一个寄存器中,然后在内存引用中使用这个寄存器

  • C操作符 * 执行指针的间接引用
long x = *xp                    // pointer dereferencing

将读存储在xp所指位置的值,并将它放在名字为x的局部变量中

  • C操作符 & 称为取址操作符,创建一个指针。
long a = 4;
long b = exchange(&a, 3);
printf("a = %ld, b = %ld\n", a, b)

这段代码打印出

a = 3 , b = 4

该指针指向保存局部变量a的位置,然后函数exchange()将用3覆盖存储在a中的值,但是返回原来的值4作为函数的值。


压入和弹出栈数据

栈在处理过程调用中起到至关重要的作用。

栈是一种数据结构,可以添加或者删除值,不过要遵循“后进先出”的原则。

通过push将数据压入栈中,通过pop操作删除数据。

指针%rsp保存着栈顶元素的地址,x86-64中栈是向下增长的,所
以压栈是减小指针的值,出栈是增大指针的值。


加载有效地址

加载有效地址(load effective address)指令leaq实际上是movq指令的变形。

它的指令形式是从内存读数据到寄存器,但实际上它并没有引用内存。

leaq S, D                  // D <- &S

它的第一个操作数看上去是一个内存引用,但是该指令并不是从指定的位置读入数据,而是将有效地址写入目的操作数。这条指令可以为后面的内存引用产生指针。

你可能感兴趣的:(计算机系统)