程序的机器级表示(一)(关于程序员,这些汇编知识就够了)

深入理解计算机系统_第三章_程序的机器级表示 深入,并且广泛 -沉默犀牛 文章导读 计算机执行机器代码,用字节序列编码低级的操作,包括处理数据、管理内存、读写存储设备上的数据,以及利用网络通信。编译器基于编程语言的规则、目标机器的指令集和操作系统遵循的惯例,经过一系列的阶段生成机器代码。GCC C语言编译器以汇编代码的形式产生输出,汇编代码是机器代码的文本表示,给出程序中的每一条指令,然后GCC调用汇编器和链接器,根据汇编代码生成可... 阅读详情

本篇主要包括以下内容:

1. 为什么还要学汇编?

1.1 Linux下C语言转汇编及反汇编
1.2 汇编语言相对于高级语言的特点

2. 学会汇编

2.1 学习汇编要先了解的基本知识 —— 本节及其以上都是学来吹牛逼的
2.2 汇编的数据类型 —— 相对于其他语言,类型少的可怜
2.3 汇编的常用指令 —— 这是个假的重点,看看就行了
2.4 高级语言中条件循环等语句在汇编层怎么实现的 —— 没错,我觉得这个才是重点
2.5 高级语言中函数调用在汇编层的实现过程 —— 重点,重点,重点,专治各种不会传参
2.6 数组在汇编层实现 —— 重点,数组和指针,还在傻傻分不清楚?
2.7 结构体、联合等结构在汇编层实现 —— 重点,或者说深度探索c结构模型,解释字节对齐的原理等
2.8 x86_64汇编补充 —— 就是64位机下的汇编,64位机是趋势,你确定你不看看

3.用汇编做点事

3.1 汇编和gdb —— 下次面试官问你平时怎么找错就不虚了
3.2 汇编和黑客 —— 还记得多年前的梦想吗

鉴于这篇内容较多,所以我根据章节将内容分成了三篇,以下是三篇的地址:

一、为什么还要学习汇编?

 网上有很多人讨论,在现在各种高级语言争芳斗艳,各显其能的时候,我们还有必要学习汇编吗?

 作为一个应届生,关于这个问题我自己一开始想的是,有时间的话肯定要学一学,为的是在校招场上能有一项与众不同的技能,说不定可以惊艳一下面试官。但是,当我经历了几场面试后,我发现很多面试官并不在乎你会不会汇编或者更底层的知识,会这些知识好像并没有引起他们的好奇。说白了,企业只是各取所需,在你掌握的知识领域有他们想要的,并且你的掌握程度达到了他们的要求,他们才会对你感兴趣,很少会因为你了解了某个尖钻并且无人问津的知识但是对于他们企业无用的知识而对你感兴趣。所以,学习汇编的这个原因好像已经很难说服别人了。

 但是,即使是明白了这点之后,我还是坚持并且信心满满的学习汇编,因为我发现自己以前的想法过于短视,汇编是一门独特的语言,汇编和其他高级语言不一样,它不是一门用来创造生产的语言,这也不是它的长处,我们不能用评价普通高级语言的角度去评价汇编。

 我认为,汇编是一门研究性的语言,汇编语言很强大,它强大的背后是它和操作系统,计算机硬件的直接交流,我们学习操作系统,计算机体系结构,学完之后我们建立了对于计算机一个大概的认识,知道了对计算机内部结构高度抽象形成的一些概念,但是就算知道了这些概念,对于我们来说又有什么大的改变呢,当你敲下一行行c代码,你真的懂得你所敲下的c代码在计算机底层做了什么,比如一个经常用的printf函数,你只知道你调用这个函数,传入几个参数,屏幕上就会出现字符,但是这个过程真正是怎样的呢?我们在写程序的时候,被告知不能这样写,那样写会出现内存错误,我们用经验解决了这些问题,但是我们真正对这些问题产生的原因了解多少?

 对于计算机系统这个黑盒子,我们一无所知,而真正能打开这个黑盒子,我觉得就是汇编语言,学习汇编语言会将我们之前学过的操作系统知识和真正的开发工作联系起来,当我们清楚的知道自己敲下的每个字符在计算机底层的活动时,发生的错误就会更少,我们面对计算机也会更加自信。

 当担心程序会不会出错不再成为每天的主要活动时,限制你的就不是技术,而是想法。

1.1 Linux下C语言转汇编及反汇编

 在弄清楚汇编语言的好处之前,我们有必要先看看汇编语言长什么样子?汇编语言存在在哪里?

 众所周知,c语言经过预处理、编译、汇编、链接才形成可执行文件,C语言转换为汇编代码就是在编译这一阶段产生的。
这里写图片描述

示例

假如我们给定一个code.c的c语言源程序,在Linux下可以使用下面的命令让编译过程停留在编译阶段并且指定产生的汇编文件为code.s:

gcc -O1 -S code.c -o code.s

编译选项-O1告诉编译器使用第一级优化,关于gcc的编译优化等级,可以参考这篇文章:GCC编译器优化选项分析及具体优化了什么
-S选项表示将编译过程截止到编译,这是产生的输出文件就是源代码对应的汇编代码,使用-o选项制定输出文件

示例的hello.c内容如下:

int accum = 0;

int sum(int x, int y)
{
    int t = x + y;
    accum += t;
    return t;
}

通过上条命令产生的汇编代码如下:

sum:
    pushl   %ebp
    movl    %esp, %ebp
    movl    12(%ebp), %eax
    addl    8(%ebp), %eax
    addl    $eax, accum
    popl    %ebp
    ret

在上面的汇编代码中,pushl,movl,popl,ret等都是汇编指令,它们每个都对应一条机器指令,每条指令都都只会处理一个非常简单的任务。
同时,在c语言对应的汇编语言中已经除去了所有局部变量名和数据类型,并将其转换为相应的寄存器名称和地址引用。但是对于全局变量accum,暂时采用c代码中的变量名,这是因为编译器还不确定这个变量在存储器的哪个位置,一旦知道这个变量的存储器地址,就会将变量名替换为相应的地址信息。

反汇编

我们还可以使用-c命令行选项,使编译过程停留在汇编阶段。产生经过汇编器汇编过得.o文件

gcc -O1 -c code.c -o code.o

目标代码文件code.o是二进制格式,所以无法直接查看。这时候我们就要使用我们的反汇编器(disassembler),Linux下objdump命令就可以对目标程序进行反汇编,使用objdump的-d项进行反汇编示例如下:

objdump -d code.o

关于objdump命令的更多用法,可以参考这篇文章:objdump命令
结果如下:(遵照原书作者,斜体字并不是命令的输出,而是为了理解加上的注释)

这里写图片描述

上面输出的offset栏表示该指令的机器码在.o文件中的位置,Bytes栏表示该指令的机器码表示,Equivalent assembly language表示机器码等价的汇编指令。

值得说明的是反汇编出来的汇编指令与我们编译出来的汇编指令有些许差距,编译出来的汇编指令每个指令后面会跟着该指令所处理的的字节长度,如pushl中的‘l’,这些大小指示符在反汇编中被忽略,反汇编的结果是保证我们看清楚程序的逻辑,所以这些后缀的忽略对我们的分析影响不大。

上面列出的编译之后的汇编语言只包含了真正编译结果的一部分,其中还有一部分未列出,这些命令主要都是以’.’开头的汇编器和链接器的命令,这些都不是我们研究的重点,所以我们暂且忽略这些命令。

这里写图片描述

1.2 汇编语言相对于高级语言的特点

对于汇编语言,我们已经有了一个大概的认识,下来我们看看汇编语言和高级语言的特点:

汇编语言和高级语言各有千秋。首先,我们看看高级语言的相对于汇编语言的优点:

1.高级语言相对于汇编语言提供的抽象级别高,会带来更高的工作效率和可靠性。

2.编译器为我们提供了类型检查等一系统防御措施,避免很多程序错误。

3.现代的优化编译器产生的代码至少与一个熟练的汇编语言程序员手工编写的代码一样有效。

4.高级语言的可移植性。

汇编语言相对于高级语言的优点:

1.我们可以通过分析程序的汇编代码来分析优化代码中隐含的低效率。

2.高级语言的抽象隐藏了我们想要了解的程序运行时的行为信息。

3.程序在遭受病毒时,很多程序漏洞都是汇编级的。

所以学习汇编在很多时候还是很有必要的。

程序员学习汇编代码的需求随着时间的推移也发生了变化,开始时只要求程序员能直接用汇编语言编写程序,现在则是要求他们能够阅读和理解编译器产生的代码。

计算机内功修炼:程序的机器级表示(C与汇编) C与汇编, 揭秘程序的机器级别的表示 阅读详情

相关推荐

深入理解计算机系统 --- 程序的机器级表示

推荐一本书《C++反汇编与逆向分析技术揭秘》 业精于勤而荒于嬉,行成于思而毁于随。 3.程序级的机器表示 计算机执行机器代码,用字节序列编码低级的操作 编译器基于编程语言的规则、目标机器的指令集和操作系统遵循的惯例 经过一系列的阶段生成机器代码 GCC C语言编译器以汇编代码的形式产生输出,汇编代码是机器代码的文本表示 然后GCC调用汇编器和链接器,根据汇编代码生产可执行的机器代码 高级语言(如J...

qq_34916272的博客 2954

程序的机器级表示

Intel处理器的系列和架构演进: Intel处理器系列俗称x86,此处引入IA32的概念,作为x86_64的32位前身,于1985年提出,是Intel机器语言之选。 8086(1978)->i386(1985)->Pentium(1993)->Core(2006) 对于使用机器级代码的机器级编程而言,有两种重要抽象: 指令集体系结构或指令集架构(Instruction Set Architecture, ISA),来定义机器级程序的格式和行为; 机器级程序使用的内存地址是虚拟地址,所提

To the beyond and infinity! 1709

第 3 章 程序的机器级表示

文章目录第 3 章 程序的机器级表示3.1 历史观点3.2 程序编码3.3 数据格式3.4 访问信息3.5 算数和逻辑操作3.6 控制3.7 过程3.8 数组分配和访问3.9 异数的数据结构3.10 在机器级程序中将程序与控制结合起来3.11 浮点代码3.12 小结参考文献说明家庭作业练习题答案 第 3 章 程序的机器级表示                   3.1 历史观点 &nbs

lyw4631的博客 611

第3章--程序的机器级表示

对于机器级编程来说,其中两种抽象尤为重要。第一种是由指令集体系结构或指令集架构来定义机器级程序的格式和行为,它定义了处理器状态、指令的格式,以及每条指令对状态的影响。第二种抽象是,机器级程序使用的内存地址是虚拟地址,提供的内存模型看上去是一个非常大的字节数组。x86-64的机器代码和原始的C代码差别非常大。程序内存包括:程序的可执行机器代码,操作系统需要的一些信息,用来管理过程调用和返回的运行时栈,以及用户分配的内存块。一条机器指令只执行一个非常基本的操作。

qq_38500362的博客 541

OpenWrt南京电信PPPoE IPv6配置:从零搭建稳定双栈网络

本文详细指导如何在南京电信PPPoE宽带环境下,为OpenWrt路由器配置稳定的IPv6双栈网络。核心在于正确设置WAN6接口为DHCPv6客户端,并请求/60前缀,同时配置LAN口分发地址并放行防火墙关键流量,确保内网设备获得原生IPv6连接。

water的专栏 1342

ESP32编译卡在‘Cannot establish a connection to the component registry’?别急着重装,先试试这两个国内镜像配置

本文详细解析了ESP32编译过程中常见的‘Cannot establish a connection to the component registry’报错问题,并提供了国内镜像源的配置方案。通过对比Gitee、清华大学、阿里云和中科大等镜像源的性能,帮助开发者快速解决网络连接问题,提升编译效率。文章还包含手把手的配置教程和进阶技巧,适用于ESP-IDF开发环境的优化。

weixin_34088048的博客 341

《深入理解计算机系统(CSAPP)》第3章 程序的机器级表示 - 学习笔记

计算机执行机器代码,用字节序列编码低级的操作,包括处理数据、管理内存、读写存储设备上的数据,以及利用网络通信。编译器基于编程语言的规则、目标机器的指令集和操作系统遵循的惯例,经过一系列的阶段生成机器代码。GCCC语言编译器以汇编代码的形式产生输出,汇编代码是机器代码的文本表示,给出程序中的每一条指令。然后 GCC调用汇编器和链接器,根据汇编代码生成可执行的机器代码。在本章中,我们会近距离地观察机器代码,以及人类可读的表示一汇编代码。

友人帐_的博客 2775

什么事LLVM和Clang?Clang与GCC有什么区别?Clang如何使用?

这个问题主要讲Xcode编译器的认知,在学习iOS之前有必要学习一下Objective-C的编译环境。 在了解LLVM和Clang之前,先得了解一下什么是编译器。 编译器是一种计算机程序,它将某种编程语言(高级编程语言)写成的源代码转换成另一种编程语言(低级编程语言)。一个现代编译器的主要工作流程为:源代码->预处理器->编译器->目标代码->链接器->可执行程序...

Welcome~ 9724

深入理解计算机系统:程序的机器级表示

深入理解计算机系统(第三版)

学习记录 1612

EB Tresos激活失败?3种实用解决方案帮你搞定(含离线激活步骤)

本文针对EB Tresos软件激活失败问题,提供了三种实用的解决方案。详细分析了激活失败的常见根源,并系统阐述了在线环境下的排查步骤、无网环境下的离线激活全流程,以及高级许可证环境修复方法,帮助汽车电子工程师快速恢复开发环境。

milk8的博客 609

保姆级教程:用BMS的HVIL检测电路,手把手教你排查高压互锁故障(附PWM/直流源方案对比)

本文详细解析了BMS中的HVIL检测电路,通过对比直流源与PWM两种方案,提供了一套系统化的高压互锁故障诊断流程。从电路原理到实战技巧,帮助维修人员精准定位故障根源,提升电动汽车高压系统的安全性和可靠性。

weixin_29300241的博客 392

第三章 程序的机器级表示

程序的机器级表示 计算机执行机器代码,用字节序列编码低级的操作,包括处理数据、管理内存、读写存储设备上的数据,以及利用网络通信。编译器基于编程语言的规则、目标机器的指令集和操作系统遵循的惯例,经过一系列的阶段生成机器代码。GCC C语言编译器以汇编代码的形式产生输出,汇编代码是机器代码的文本表示,给出程序中的每一条指令,然后GCC调用汇编器和链接器,根据汇编代码生成可执行的机器代码。 当我们有高级语言编程的时候,机器屏蔽了程序的机器级的实现。而使用汇编语言编程的时候,程序员就必须制定程序用来执行计算的低级指

ai_do的博客 1243

【Linux命令大全】006.网络通讯之write命令(实操篇)

Linux write命令摘要 write是Linux系统中用于用户间实时通讯的命令工具,允许向其他登录用户的终端发送消息。主要功能包括: 基本使用:通过write username向指定用户发送消息,Ctrl+D结束输入 终端指定:当用户登录多个终端时,可用write username tty指定目标终端 实用技巧: 使用who查看在线用户 通过管道发送单行消息:echo "内容" | write user 支持多行消息发送和简单聊天会话。

yuhuasheng1997的博客 216

程序的机器级表示——Intel x86 汇编讲解

程序的汇编指令讲解。

weixin_37620587的博客 2137

用 OP-TEE 给 AI 模型“上锁”:密文存储、TEE 解密放行、推理后销毁(实战可落地)

本文提出一种基于OP-TEE的AI模型保护方案,通过两级密钥体系确保模型静态存储为密文,运行时仅在TEE内解密。方案采用KEK+DEK架构,DEK永不出TEE,支持分块解密与可验证擦除。该方案能有效防御静态分析、应用层逆向等威胁,但需承认其物理级攻击的局限性。文章详细描述了端到端架构、文件格式设计及TA实现要点,包括密钥管理、分块解密策略和销毁机制,为设备侧AI部署提供了工程可行的安全解决方案。

Interview_TC的博客 290

MATLAB从入门到精通-APP调用simulink中的参数,并且修改,将结果返回到APP中

本次案例为以下微分方程: 其中方程的初始值为: Step1:搭建simulink文件,如下图所示: 初始值配置在积分模块中,如下图所示: Step2:制作app 操作视频: ,时长01:11 代码: 本文包括APP如何回调simulik中d的参数,以及把simulink中的仿真结果输出到APP中的绘图界面中。 核心代码如下: ...

wenyusuran的专栏 3042

CSAPP阅读笔记-程序的机器级表示

程序的机器级表示 计算机执行机器代码,用字节序列编码低级的操作,包括处理数据、管理内存、读写存储设备上的数据,以及利用网络通信。编译器基于编程语言的规则、目标机器的指令集和操作系统遵循的惯例,经过一系列的阶段生成机器代码。GCC C语言编译器以汇编代码的形式产生输出,汇编代码是机器代码的文本表示,给出程序中的每一条指令。然后GCC调用汇编器和链接器,根据汇编代码生成可执行的机器代码。

苹果好吃呀的博客 763

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

程序的机器级表示(一)

程序编码 假设一个C程序,有两个文件p1.c和p2.c。我们用Unix命令行编译这些代码: linux> gcc -Og-o p p1.c p2.c    命令gcc就是GCC编译器,这是Linux默认的编译器。编译选项-Og告诉编译器使用会生成符合原始C代码整体结构的机器代码的优化等级,使用较高级别的优化产生的代码会严重变形,以至于产生的机器代码和初始源代码之...

weixin_30432007的博客 289

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

深入理解操作系统(5)第三章:程序的机器级表示(1)intel历史+程序编码+算术和逻辑操作(包括:8086/汇编/摩尔/机器级代码/汇编指令/objdump/汇编指令/反汇编/8个常用寄存器/lea

深入理解操作系统(5)第三章:程序的机器级表示(1)intel历史+程序编码+算术和逻辑操作(包括:8086由来/汇编/摩尔定律/机器级代码/汇编指令特性/objdump/汇编指令/反汇编/8个常用寄存器/操作数的三种类型/lea指令/移位操作sall,shll)1. 前言1.1 现代编译器的优点1.2 理解汇编代码的重要性1.3 编译器的优化1.4 精通细节是理解更深和更基本概念的先决条件2. 历史观点-Intel处理器发展2.1 intel历史(8086由来)2.2 IA32-Intel32位体系结构2

哈尼的博客 3454

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

用来表示代码块_深入理解计算机系统-程序的机器级表示

知乎对于表达式语法支持不太行,大家可以去看原文深入理解计算机系统-程序的机器级表示 - 掘金​juejin.im程序的机器级表示前言汇编代码与特定机器密切相关,能够阅读和理解汇编代码是一项很重要的技能。历史观点这,没啥很好说的,就,无了。程序编码对于Linux机,可以使用 gcc -Og -S xxx.c来进行学习。因为参数-Og表明不进行优化,这可以让汇编代码尽可能地保持和C源码一样的顺序,位置...

weixin_29759387的博客 674

高级语言与机器级代码之间的对应

要先把32bit的被除数扩展为64位的然后再除以除数, 我们说以E开头的为32位所以,64bit要用两个寄存器。X86就是能被能够被以86结尾的CPU(如8086,80286,80386)支持的汇编语言指令。往年的408都是考察intel格式的, 所以重点还是之前的知识。被除数是被提前放在edx和eax中,是隐含寻址。所以题目中说IP程序计数器也就是PC程序计数器。只有可能来源于寄存器或主存不可能来源于常量。Dword 代表 32bit。word 代表16bit。右边的方式比左边灵活的多。

qq_61866637的博客 809

第3章“程序的机器级表示”:程序编码 和 数据格式

反编译器、汇编代码中的格式

明朗晨光的专栏 993

CSAPP《深入理解计算机系统》深读笔记4——第三章-程序的机器级表示(一)

CSAPP《深入理解计算机系统》深读笔记4——第三章-程序的机器级表示(一)

拉依达不拉跨的博客 1185

理解计算机系统_程序的机器级表示(一):程序编码和数据

以<深入理解计算机系统>(以下称“本书”)内容为基础,对程序的整个过程进行梳理。本书内容对整个计算机系统做了系统性导引,每部分内容都是单独的一门课.学习深度根据自己需要来定。

jllws1的博客 922

《深入理解计算机系统》学习笔记:程序的机器级表示

目录概述一、历史观点二、程序编码2.1、机器级代码 概述 计算机执行机器代码,用字节序列编码低级的操作,包括处理数据、管理内存、读写存储设备上的数据、以及利用网络通信。 编译器基于编程语言的规则、目标机器的指令集和操作系统遵循的惯例,经过一系列的阶段生成机器代码。 当我们使用高级语言编程的时候(例如C语言,Java语言更是如此),机器屏蔽了程序的细节,即机器级的实现。相对于采用汇编代码进行编程的时候,最大的优点是,用高级语言编写的程序可以在很多不同的机器上编译和执行,而汇编代码则是与特定机器密切相关的。 程

npc666666的博客 1970
上一篇: 20170525_WPSC++实习_电话面试
下一篇: 八大排序算法的时间复杂度
Findway_
博客等级 码龄10年 36粉丝 117原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值