打开汇编之门

vscode搭建汇编环境 一、安装MASM/TASM插件 二、配置DOS的环境和选择编译器 汇编调试什么需要在dos系统上(目前是这么理解的),所以要想办法弄出这个环境来,其次还需要编译器。因为汇编程序生成exe即可执行文件的过程中,需要先编译生成obj文件,然后再链接生成exe。生成exe后才可进行调试。 设置如下 选择如下(我看其他文章也有选择其他的,大家可以都试试,现在我还不懂,等懂了再过来解释) 三、调试一下子 随便写一个程序,然后右键选择调试 2.结果 3.测试代码 assume cs:z. 阅读详情

 来源: http://bigwhite.blogbus.com/logs/2005/11/1587340.html

 
    工作这么长时间,一直在C语言这一层面上钻研和打拼,日积月累,很多关于C的疑惑在书本和资料中都难以找到答案。程序员是追求完美的一个种群,其头 脑中哪怕是存在一点点的思维黑洞都会让其坐卧不宁。不久前在itput论坛上偶得《Computer Systems A Programmer's Perspective》(以下称CS.APP)这本经典好书,遂连夜拜读以求解惑。虽说书中没有能正面的回答我的一些疑惑,但是它却为我指明了一条通向 “无惑”之路 -- 这就是打开汇编之门。

汇编语言是一门非常接近机器语言的语言,其语句与机器指令之间的对应关系更加简单和清晰。打开汇 编之门不仅仅能解除高级语言给你带来的疑惑,它更能让你更加的理解现代计算机的运行体系,还有一点更加重要的是它给你带来的是一种自信的感觉,减少了你在 高处摇摇欲坠的恐惧,响应了侯捷老师的“勿在浮沙筑高台”的号召。现在学习汇编的目的已与以前大大不同了。正如CS.APP中所说那样“程序员学习汇编的 需求随着时间的推移也发生了变化,开始时是要求程序员能直接用汇编编写程序,现在则是要求能够阅读和理解优化编译器产生的代码”。能阅读和理解,这也恰恰 是我的需求和目标。

在大学时接触过汇编,主要是Microsoft MASM宏汇编,不过那时的认识高度不够加上态度不端正,错失了一个很好的学习机会。现在绝大部分时间是使用GCC在Unix系列平台上工作,选择汇编语 言当然是GNU汇编了,恰好CS.APP中使用的也是GNU的汇编语法。由于学习汇编的主要目的还是“解惑”,所以形式上多是以C代码和汇编代码的比较。

1、汇编让你看到更多
随 着你使用的语言的层次的提高,你眼中的计算机将会越来越模糊,你的关注点也越来越远离语言本身而靠近另一端“问题域”,比如通过JAVA,你更多看到的是 其虚拟机,而看不到真实的计算机;通过C,你看到的也仅仅是内存一层;到了汇编语言,你就可以深入到寄存器一层自由发挥了。汇编程序员眼里的“独特风景” 包括:
a) “程序计数器(%eip)” -- 一个特殊寄存器,其中永远存储下一条将要执行的指令的地址;
b) 整数寄存器 -- 共8个,分别是%eax、%ebx、%ecx、%edx、%esi、%ebi、%esp和%ebp,它们可以存整数数据,可以存地址,也可以记录程序状态 等。早期每个寄存器都有其特殊的用途,现在由于像linux这样的平台多采用“平面寻址[1]”,寄存器的特殊性已经不那么明显了。
c) 条件标志寄存器 -- 保存最近执行的算术指令的状态信息,用来实现控制流中的条件变化。
d) 浮点数寄存器 -- 顾名思义,用来存放浮点数。
虽说寄存器的特殊性程度已经弱化,但是实际上每个编译器在使用这些寄存器时还是遵循一定的规则的,以后再说。

2、初窥汇编
下面是一个简单的C函数:
void dummy() {
 int a = 1234;
 int b = a;
}
我们使用gcc加-S选项将之转换成汇编代码如下(省略部分内容):
 movl $1234, -4(%ebp)
 movl -4(%ebp), %eax
 movl %eax, -8(%ebp)
看 了一眼又一眼,还是看不懂,只是发现些熟悉的内容,因为上面提过如%ebp、%eax等。这只是个引子,让我们感性的认识一下汇编的“容貌”。我们一点点 地来看。咋看一眼汇编代码长得似乎很相似,没错,汇编代码就是一条一条的“指令+操作数”的语句的集合。汇编指令是固定的,每条指令都有其固定的用途,而 操作数表示则有多种类型。

1) 操作数表示
大部分汇编指令都有一个或多个操作数,包括指令操作中的源和目的。一条标准的指令格式大 致是这样的:“指令 + 源操作数 + 目的操作数”,其中源操作数可以是立即数、从寄存器中读出的数或从内存中读出的数;而目的操作数则可以是寄存器或内存。按这么一分类,操作数就大致有三 种:
a) 立即数表示法 -- 如“movl $1234, -4(%ebp)”中的“$1234”,就是一个立即数作为操作数,按照GNU汇编语法,立即数表示为“$+整数”。立即数常用来表示代码中的一些常数, 如上例中的“$1234”。注意一点的是立即数不能作为目的操作数。
b) 寄存器表示法 -- 这种比较简单,它就是表示寄存器之内容。如上面的“movl -4(%ebp), %eax”中的%eax就是使用寄存器表示法作源操作数,而“movl %eax, -8(%ebp)”中的%eax则是使用寄存器表示法作目的操作数。
c) 内存引用表示法 -- 计算出的该操作数的值表示的是相应的内存地址。汇编指令根据这个内存地址访问相应的内存位置。如上例“movl -4(%ebp), %eax”中的“-4(%ebp)”,其表示的内存地址为(%ebp寄存器中的内容-4)得到的值。

2) 数据传送指令
汇编语言中最最常用的指令 -- 数据传送指令,也是我们接触的第一种类别的汇编指令。其指令的格式为:“mov 源操作数, 目的操作数”。
mov 系列支持从最小一个字节到最大双字的访问与传送。其中movb用来传送一字节信息,movw用来传送二字节,即一个字的信息,movl用来传送双字信息。 这些不详说了。除此以外mov系列还提供两个带位扩展的指令movsbl和movzbl,我们举个例子来说明一下这两个特殊指令的作用何在:

a) movzbl指令
void dummy1() {
 unsigned char c = 'a';
 unsigned int a = c;
}
其对应的GNU汇编为(省略部分内容):
 movb $97, -1(%ebp)   //'a'的ASCII码为97
 movzbl -1(%ebp), %eax
 movl %eax, -8(%ebp)
说 明:在dummy1函数中“unsigned int a = c”语句完成的是一个从unsigned char到unsigned int的赋值操作,由于int的类型长度大于char类型长度,所以实际是将一个字节的内容拷贝到一个可以容纳4个字节的地方,这样的话需要对源数据进行 一下扩展,即填充高位的3个字节。

如何填充呢?由于变量a和c都为无符号整型,所以只需要填充0即可。而movzbl就是干这个活的。movzbl指令负责拷贝一个字节,并用0填充其目的操作数中的其余各位,这种扩展方式叫“零扩展”。

b) movsbl指令
void dummy2() {
 signed char c = 'a';
 unsigned int a = c;
}

其对应的GNU汇编为(省略部分内容):
 movb $97, -1(%ebp)   //'a'的ASCII码为97
 movsbl -1(%ebp), %eax
 movl %eax, -8(%ebp)
说 明:在dummy2函数中“unsigned int a = c”语句完成的是一个从signed char到unsigned int的赋值操作,由于int的类型长度大于char类型长度,所以实际是将一个字节的内容拷贝到一个可以容纳4个字节的地方,这样的话需要对源数据进行 一下扩展,即填充高位的3个字节。如何填充呢?GNU汇编告诉我们它使用了变量c的最高位来填充其余的3个字节。movsbl指令负责拷贝一个字节,并用 源操作数的最高位填充其目的操作数中的其余各位,这种扩展方式叫“符号扩展”。实际上dummy2中变量a还是保留了变量c的符号位的,起码GCC是这么 做的。

c) 在CS.APP中pushl和popl也别归入“数据传送指令”类别,但对于刚入门选手这两个指令还是稍显复杂,在以后谈到“procedure”时再细说。

3、小结
已经迈出了踏入汇编之门的第一步,汇编的确让我眼前敞亮了许多,看得多了,知道得多了,疑惑也就少了。

4、参考资料
1) 《Computer Systems A Programmer's Perspective》

[注1]
平面寻址:简单的将存储器看成一个大的、按照字节寻址的数组。不区分类型、符号、地址还是整数。注意汇编程序员看到也是进程空间的虚拟地址。

educoder|用MARS4_5打开汇编源程序 用MARS打开MIPS汇编源程序的方法介绍。规避“不支持的二进制文件”报错。 阅读详情

相关推荐

西湖论剑2023 Dual personality writeup ——天堂之门技术的分析

天堂之门技术分析

qq_41866334的博客 1765

movzbl和movsbl

汇编语言中最最常用的指令 -- 数据传送指令,也是我们接触的第一种类别的汇编指令。其指令的格式为:“mov 源操作数, 目的操作数”。mov系列支持从最小一个字节到最大双字的访问与传送。其中movb用来传送一字节信息,movw用来传送二字节,即一个字的信息,movl用来传送双字信息。这些不详说了。除此以外mov系列还提供两个带位扩展的指令movsbl和movzbl,我们举个例子来说明一下这两个特殊...

weixin_30415113的博客 7298

使用反汇编工具IDA查看发生异常的汇编代码的上下文去辅助分析C++软件异常

本文详细介绍如何使用反汇编工具IDA查看发生异常的汇编代码的上下文去辅助分析C++软件异常,并给出了问题分析实例。

dvlinker的技术专栏 3万+

汇编/源操作数/目的操作数

目标操作数是通用寄存器,源操作数可以是立即数、通用寄存器或内存位置。 1、源操作数是指接收的数据,包括地址和目的操作数指结果。操作数就是要处理的数据。数据就是数值,也就是我们通过观察、实验或计算得出的结果。数据有很多种,最简单的就是数字。数据也可以是文字、图像、声音等。数据可以用于科学研究、设计、查证等。 2、数据传送指令一般都是操作数自源地址单元传送到目的地址单元 指令执行后源地址单元的操作不变...

Stitch__的博客 2万+

分析C++软件异常需要掌握的汇编知识汇总

本文详细地讲述排查C++软件异常时所要了解和掌握的一些汇编方面的基本知识与要点。

dvlinker的技术专栏 2万+

深入理解计算机系统(英文,computer systems a programmer's perspective)

从程序员的视角,看计算机系统! 本书适用于那些想要写出更快、更可靠程序的程序员。通过掌握程序是如何映射到系统上,以及程序是如何执行的,读者能够更好的理解程序的行为为什么是这样的,以及效率低下是如何造成的。粗略来看,计算机系统包括处理器和存储器硬件、编译器、操作系统和网络互连环境。而通过程序员的视角,读者可以清晰地明白学习计算机系统的内部工作原理会对他们今后作为计算机科学研究者和工程师的工作有进一步的帮助。它还有助于为进一步学习计算机体系结构、操作系统、编译器和网络互连做好准备。 本书的主要论题包括:数据表示、C程序的机器级表示、处理器结构,程序优化、存储器层次结构、链接、异常控制流、虚拟存储器和存储器管理、系统级I/O、网络编程和并发编程。书中所覆盖的内容主要是这些方面是如何影响应用和系统程序员的。例如,在讲述数据表示时,本书说明了用来表示数字的表示方法是有限的,它能够近似地表示整数和实数,但是这种表示方法是有限制的,程序员必须了解。在讲述高速缓存时,本书讨论了矩阵代码中的循环变量的顺序是如何影响程序的性能的。在讨论网络互连时,本书描述了并发服务器如何能有效地处理来自多个客户端的请求。

数据传输指令

mov指令有5中形式 源目的地址:立即数,寄存器,存储器 目的地址:寄存器,存储器 (存储器不能到存储器) movl 传送双字 movb 传送一个字节 movw 传送两个字节 这里注意: movsbl movzbl 指令负责拷贝一个字节,并设置目的操作数其余的位 区别在于: movsbl源操作数是单字节,将24位设置位源字节的最高位,然后拷贝到双字目的中 movzbl 源操作

fourous的博客 4891

VS2005版本的Perspective v0.923

开源的wiki引擎,官方版本.NET 1.1,我升级为版本.NET 2.0

汇编学习(下)

汇编入门学习笔记

qq_44555676的博客 1万+

Win10+pycharm+conda 配置Siammask 过程记录(新手向)

我们跑动demo 需要配置两个相关的文件这两个文件需要用 git 进行下载,对于不熟悉git的小伙伴 我这里给出连接,大家可以直接下载即可,并将其配置在 experiments文件夹下然后大家再需要在设置参数参数这里给出了。

C1137577723的博客 551

智能气象站:ESP32驱动的心知天气数据可视化实践

本文详细介绍了基于ESP32微控制器和心知天气API构建智能气象站的完整实践。通过Arduino开发环境,实现天气数据的获取、JSON解析与OLED屏可视化展示,涵盖硬件连接、API配置、低功耗优化及部署问题排查,为物联网开发者提供实用指南。

jump7的博客 210

第3章“程序的机器级表示”:访问信息

访问信息的方式:数据传送指令以及示例

明朗晨光的专栏 1276

什么是 SAP ABAP Secure Storage

此过程将单独的密钥存储在密钥路径中的密钥文件中,并自动使用新加密密钥加密安全存储中的所有数据记录。需要注意的是,不要在没有命令行工具的情况下操作密钥文件,例如,不要用不同的版本替换密钥文件,否则,安全存储中的数据记录可能变得不可读。当需要访问这些数据时,系统会对其进行解密。文件系统中的安全存储(Secure Storage in the File System)也是 SAP NetWeaver Application Server for ABAP 的一部分,主要用于安全存储连接相关的数据,如密码等。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 439

【亲测免费】 推荐文章:《探索GB汇编教程之旅》—— 打开Game Boy开发的神秘之门

推荐文章:《探索GB汇编教程之旅》—— 打开Game Boy开发的神秘之门 在技术的浩瀚海洋中,复古游戏开发无疑是一块独特的领域,而今天我们将带你领略的是一个专为Game Boy平台定制的开源学习资源——GB ASM tutorial v2。这不仅是一个重启并决心完善到底的教程,更是一把解锁古老游戏编程艺术的钥匙。 项目介绍 GB ASM tutorial v2是对先前版本的一次全面重做,旨在系统...

gitblog_00823的博客 398

基于VLFM的中文指令视觉语言导航系统设计与实现

文章摘要 本文介绍了一个基于VLFM(视觉语言边界地图)的中文指令视觉语言导航系统设计与实现。该系统采用模块化架构,包含三维场景渲染、URDF机器人仿真、VLFM导航引擎、中文指令解析和PyQt图形界面五大核心模块。系统支持自定义GLB场景模型和URDF机器人模型,通过transformers和langchain实现中文自然语言指令解析,利用VLFM算法进行语义导航决策。技术实现上详细介绍了GLB模型加载器开发、URDF机器人控制、VLFM导航算法集成以及PyQt界面设计。该系统在Ubuntu环境下运行,依

AI的内部世界的博客 208

PCB仿真软件:Altium Designer_(6).PCB布线设计:自动布线与手工布线

通过以上步骤,我们完成了一个简单的PCB设计案例。在这个过程中,我们使用了自动布线和手工布线的综合策略,确保布线质量符合设计要求。创建PCB项目:在Altium Designer中创建一个新的PCB项目。导入原理图:将原理图文件导入到PCB项目中。设置布线规则:通过设置必要的布线规则,如线宽、间距等。启动自动布线:使用自动布线器进行初步布线。手工优化布线:通过手工布线工具优化关键信号的布线路径。保存和导出PCB文件:保存PCB文件并导出Gerber文件,用于生产。

kkchenjj的博客 2522

Linux怎么打开汇编文件,linux – 如何在汇编程序中打开文件并进行修改?

我开始学习汇编程序,我在Unix工作.我想打开一个文件并在上面写上“Hello world”.section.datatextoutput db 'Hello world!', 10lentext equ $- textoutputfiletoopen db 'hi.txt'section .textglobal _start_start:mov eax, 5 ;openmo...

weixin_42304279的博客 171

深度解读华为Limera:从舱内激光视觉融合看前融合技术的发展与演进

华为Limera激光雷达摄像头融合技术推动自动驾驶感知升级 华为推出的Limera创新性地将激光雷达与摄像头深度集成,采用共光路设计实现数据天然对齐,在小型障碍物识别等关键场景展现卓越性能。该产品代表了传感器前融合技术从分立走向共生的演进趋势,通过硬件级集成解决了多源异构数据融合难题。随着索尼堆叠式传感器等技术的出现,未来智能汽车感知系统将向高度集成的"超级传感器"方向发展,实现更精准的环境感知。Limera的发布标志着前融合技术从"可用"迈向"极致&quo

致力于lidar应用开发 397

如何打开asm文件(学习汇编语言)

1.asm文件可以直接用记事本打开,浏览 2.asm文件是汇编程序源文件,可以通过debug工具汇编成.obj文件,然后用link工具连接成.exe 文件 3.可以在MASMPlus.exe 中打开, 点击编译-编译(ASM)-连接,也会生成exe文件 4.在dosbox中改变盘符,然后输入debug空格+exe文件的名称,单击回车,出现“-”符号,则文件已经打开。 ...

工科狗Niko的博客 2万+

qq对接openclaw,通过qq发送命令

把 OpenClaw 接入 QQ 和微信,目前主流的微信文章和教程主要提供了两种截然不同的路径。我为你梳理了它们的核心区别和关键步骤,你可以根据自己的需求来选择。

suny8的专栏 270

华为OD技术面真题 - 计算机网络 - 1

汇总华为OD技术面八股文计算机网络相关八股文,高频技术真题并提供详细解答。

qq_45776114的博客 1327

初步分析简单的汇编代码

初步分析简单的汇编代码 一、C语言源代码 这里注意一点:目前IDA对C++代码的分析很不友好,因此初学者分析汇编最好是分析C语言,写脚本可以使用C++或Python 提供一段简单的C语言代码 #include<stdio.h> int getsum(int x) { int sum=0,i; for(i=0;i<x;i++) sum+=i; return sum; } int main() { int n=10,ans; ans=getsum(n); printf("%d\

__ys的博客 1031

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

上一篇: 内存中inode与磁盘中inode
下一篇: Linux下汇编语言开发指南
lphpc
博客等级 码龄22年 32粉丝 86原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值