博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
程序的机器表示
阅读量:4125 次
发布时间:2019-05-25

本文共 1001 字,大约阅读时间需要 3 分钟。

计算机执行机器代码,用字节序列编码低级操作,在本篇文章中,我们会观察机器代码,以及人类可读表示–汇编代码

为什么要学习机器代码呢?即使编译器承担了生成汇编代码的大部分工作,对于严谨的程序员,能够阅读和理解汇编代码仍是一项很重要的技能,阅读汇编代码,能理解编译器的优化能力,并分析代码中隐含的低效率。

代码示例:

在这里插入图片描述
在命令行上使用‘-S’,就能看到C语言编译器产生的汇编代码

linux> gcc -Og -S mstore.c

汇编文件包含各种声明,包括下面几行:

在这里插入图片描述
如果使用‘-c’选项,GCC就会编译并汇编代码:

linux> gcc -Og -c mstore.c

这样产生目标代码文件mstore.o,它是二进制,无法直接查看,机器执行的程序只是一个字节序列,它是对一系列指令的编码

数据格式

C语言数据类型在x86-64中的大小,在64位机器,指针长8字节

在这里插入图片描述

访问信息

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

在这里插入图片描述

大多数指令有一个或多个操作数,指示使用的数据源以及放置结果的目的位置。操作数分三种类型,第一种是立即数,表示常数值,$-577、$0x1F;第二种是寄存器,表示某寄存器的内容;第三种是内存引用,根据计算出的地址访问某个内存位置。

寻址模式:

在这里插入图片描述

数据指令

数据传送指令–MOV,将数据从一个位置复制到另一个位置

在这里插入图片描述

使用数据传送指令的代码示例:

在这里插入图片描述
函数exchange由三条指令实现:两个数据传送(movq),一条返回函数被调用点的指令(ret)。

过程执行时,xpy存储在寄存器%rdi%rsi,指令2从内存读出x,放到寄存器%rax,实现x=*xp,用寄存器%rax从这个函数返回值。指令3将y写到寄存器%rdi中的xp指向的内存位置,实现*xp=y。

压入和弹出数据–pop/push

在这里插入图片描述
执行完pushq后执行popq %rdx的效果:
在这里插入图片描述
先从内存中读出值0x123,再写到寄存器%rdx,然后,寄存器%rsp值将增加到0x108,如图,值0x123仍会保持在0x100中,直到被覆盖,无论如何,%rsp指向的地址总是栈顶。

x86-64的整数和逻辑操作:

在这里插入图片描述

x86-64比较和测试指令:

在这里插入图片描述

x86-64跳转jmp指令:

在这里插入图片描述
x86-64条件传送指令:
在这里插入图片描述

gdb调试器

启动GDB:

linux> gdb prog

在这里插入图片描述

【完】?

转载地址:http://xyhpi.baihongyu.com/

你可能感兴趣的文章
动态库调动态库
查看>>
Kubernetes集群搭建之CNI-Flanneld部署篇
查看>>
k8s web终端连接工具
查看>>
手绘VS码绘(一):静态图绘制(码绘使用P5.js)
查看>>
手绘VS码绘(二):动态图绘制(码绘使用Processing)
查看>>
基于P5.js的“绘画系统”
查看>>
《达芬奇的人生密码》观后感
查看>>
论文翻译:《一个包容性设计的具体例子:聋人导向可访问性》
查看>>
基于“分形”编写的交互应用
查看>>
《融入动画技术的交互应用》主题博文推荐
查看>>
链睿和家乐福合作推出下一代零售业隐私保护技术
查看>>
Unifrax宣布新建SiFAB™生产线
查看>>
艾默生纪念谷轮™在空调和制冷领域的百年创新成就
查看>>
NEXO代币持有者获得20,428,359.89美元股息
查看>>
Piper Sandler为EverArc收购Perimeter Solutions提供咨询服务
查看>>
RMRK筹集600万美元,用于在Polkadot上建立先进的NFT系统标准
查看>>
JavaSE_day12 集合
查看>>
JavaSE_day14 集合中的Map集合_键值映射关系
查看>>
Day_15JavaSE 异常
查看>>
异常 Java学习Day_15
查看>>