前言
📫作者简介:小明Java问道之路,专注于研究计算机底层/Java/Liunx 内核,就职于大型金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的架构设计📫
🏆CSDN专家博主/Java领域优质创作者、阿里云专家/签约博主、InfoQ签约博主、华为云专家、51CTO专家🏆
🔥如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主~
本文解读
本章中,我们了解C语言机器级编程,通过让编译器产生机器级程序的汇编代码表示,了解了编译器和他的优化能力,以及机器、数据类型和指令集。
一、程序编码
gcc命令:C编译器 ;gcc -0g 代表机器代码的优化等级
机器级编程,两种抽象:一、由指令集体系结构或指令集架构来定义机器级程序的格式和行为,它定义了处理器状态、指令的格式、以及每条指令对状态的影响。二、机器级程序使用的内存地址是虚拟地址,提供的内存模型看上去是一个很大的、按字节寻址的数组。
二、数据格式
x86-64指令集包括完整的针对字节、字和双字的指令。
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位值的通用目的寄存器。这些寄存器用来存储整数数据和指针。
指令可以对这16个寄存器的低位字节中存放的不同大小的数据进行操作。生成1字节和2字节数字的指令会保持剩下的字节不变, 生成4字节数字的指令会把高位4个字节置为0(高16位)。
四、汇编指令
指令 | 效果 | 描述 | ||
数据传输指令 | ||||
mov | 传送 | |||
pushq | 压入栈 | |||
popq | 弹出栈 | |||
leaq | 加载有效地址 | 是movq指令的变形 | ||
算术和逻辑操作 | ||||
INC | 加1 | |||
DEG | 减1 | |||
NEG | 去负 | |||
NOT | 取补 | |||
ADD | 加 | |||
SUB | 减 | |||
IMUL | 乘 | |||
XOR | 异或 | |||
OR | 或 | |||
AND | 与 | |||
SAL | 左移 | |||
SHL | 左移 | |||
SAR | 算术右移 | |||
SHR | 逻辑右移 | |||
imulp | 有符号乘法 | |||
mulp | 无符号乘法 | |||
cqto | 转换为8字节 | |||
idivq | 有符号除法 | |||
divq | 无符号除法 | |||
控制 | ||||
CMP | 不修改寄存器的值,只设置条件码 | 比较 | ||
TEST | 测试 | |||
SET | 根据条件码组合set0/1 | 访问条件码 | ||
jump | 跳转到另一条带标号的目的地 | 跳转指令 | ||
cmove | 用条件传送来实现条件分支 | |||
switch_eg | 引用跳转表 | switch语句 | ||
过程 | ||||
call | 控制从函数P转移到函数Q的过程 | 转移控制 | ||
%rdi %edx…… | 寄存器中的局部存储变量 | 数据传送 |
五、理解指针
1、每个指针都有都有一个值
2、指针用 & 创建
3、* 用于间接引用指针
4、数组引用(a[3])与指针运算和间接引用(*(a+3))有一样的效果
5、将指针从一种类型强制转换成另一种类型,只改变他的类型,不改变他的值
7、指针可以指向函数(int fun(int i); int (*fp)(int i); fp = fun;)(调用:int result=fp(3))
六、小结
我们了解C语言机器级编程,通过让编译器产生机器级程序的汇编代码表示,了解了编译器和他的优化能力,以及机器、数据类型和指令集。
Java的目标代码是特殊的二进制——java字节码,可以看成是虚拟机的机器级程序,软件解释器处理字节代码。另外有一种及时编译(just-in-time compilation JIT)动态的将字节码序列翻译成机器指令。