【精通底层】全面了解程序的机器级表示

举报
小明的混沌之路 发表于 2022/07/31 13:31:27 2022/07/31
【摘要】 本章中,我们了解C语言机器级编程,通过让编译器产生机器级程序的汇编代码表示,了解了编译器和他的优化能力,以及机器、数据类型和指令集。


前言:📫 作者简介:小明java问道之路,专注于研究计算机底层,就职于金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的设计和架构📫 

🏆 Java 领域优质创作者、阿里云专家博主、华为云专家🏆

🔥 如果此文还不错的话,还请👍关注点赞收藏三连支持👍一下博主哦

本文导读

本章中,我们了解C语言机器级编程,通过让编译器产生机器级程序的汇编代码表示,了解了编译器和他的优化能力,以及机器、数据类型和指令集。

一、程序编码

gcc命令:C编译器 ;gcc -0g 代表机器代码的优化等级

机器级编程,两种抽象:一、由指令集体系结构或指令集架构来定义机器级程序的格式和行为,它定义了处理器状态、指令的格式、以及每条指令对状态的影响。二、机器级程序使用的内存地址是虚拟地址,提供的内存模型看上去是一个很大的、按字节寻址的数组。

二、数据格式

x86-64指令集包括完整的针对字节、字和双字的指令。x86-64指令集这个东西也是ISA指令集的一种,他的作用是编译用的,编译也可以分为三步 前端-》中间语言-》后端,前端就是由不同需要接入当前编译器的前端开发者进行开发,来适配多门语言,过程为 高级语言源代码-》词法分析-》语法分析-》构件AST的过程-》到中间语言,中间语言解耦,后端由不同需要接入当前编译器的后端开发进行开发,来适配多门目标机器语言(ISA),拿到中间语言-》做分析优化,最终生成目标语言。

三、访问信息

一个x86-64的中央处理器单元(CPU)包含一组16个存储64位值的通用目的寄存器。这些寄存器用来存储整数数据和指针。

指令可以对这16个寄存器的低位字节中存放的不同大小的数据进行操作。生成1字节和2字节数字的指令会保持剩下的字节不变, 生成4字节数字的指令会把高位4个字节置为0(高16位)。如下图所示。

四、汇编指令大全

数据传输指令:

mov 传送

pushq 压入栈

popq 弹出栈

leaq 加载有效地址(是movq指令的变形)


算术和逻辑操作:

INC

DEG

NEG

NOT

ADD

SUB

IMUL

XOR

OR

AND

SAL

SHL

SAR

SHR

imulp

mulp

cqto

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)动态的将字节码序列翻译成机器指令。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。