汇编语言代码例子_汇编语言 (ASM) 真要被扫进历史的垃圾堆了吗?

最近浏览一个挺流行的视频 - X天学会单片机。内容确实通俗易懂,制作的比较用心。但其中的有个观点笔者不敢苟同,就是现在 C 语言已经强大到胜任所有任务,大家没有必要再去学习汇编语言了,直接从 C 学起就行了。

这种观点似乎有一定道理,我甚至怀疑现在是不是真的有很多同学不再学习汇编了。特别是现在大多数厂商都提供了完备的驱动代码的情况下,我们做项目基本上用不到写 ASM 代码了。

ASM 就要被时代淘汰了!可真的是这样吗?

下面我们结合两个实际工程中碰到的例子谈一下,掌握 ASM 语言对我们写出稳定高效代码的必要性。

看第一个例子,为说明问题,代码我们做了简化:

635d3649a98898b913b2cf2c08464375.png

我们看代码,主程序翻转 PORTA 的引脚 0,定时中断服务程序翻转 PORTA 的引脚 1。乍一看很难看出有什么问题。有不少同学就是这么中招儿的。这要是控制一些 LED 指示灯或蜂鸣器之类的还好,最多就是偶尔看着有点乱,或出点儿噪音。要是控制设备没准儿就要出大问题了。

有什么问题呢?因为中断发生时,主程序将在上一条正在执行中的语句执行完后中止运行。这里一定要注意,这里说的语句,不是一条 C 语句,而是一条 ASM 语句。我们在调试环境看一下反汇编。一条 C 语句被编译成了多条 ASM 语句。

5251d1bd812575874b747fef26c34098.png
db07c2bf82e219c42a0ee37db9e8c58c.png

LDRH r1, [r5,#0x14] (1)

EORS r1,r1,r4 (2)

STRH r1,[r5,#0x14] (3)

我们看到一条 C 语句实际上编译为 3 句 ASM,(1)把 PORTA 当前内容读进 r1,(2)最低位通过异或取反,(3)把取反后的值输出至 PORTA。如果中断恰好发生在 (1)或 (2)的执行期间,那么中断服务程序对 PORTA 引脚 1 的操作,会被主程序中语句(3)覆盖掉。

要避免这种情况,可以在操作 IO 端口(或其它类似的操作)前禁止中断,操作完之后再允许中断。在一些有位带(Bit Map)的单片机里,对单个引脚的操作可以通过位带区操作,避免各引脚之间互相影响。

汇编语言的使用,还可以大幅度的提高代码的效率。即使现在编译器的效率已经挺高了,但毕竟机器还是要比人笨一点儿。举个栗子,有不少工程里面需要用到浮点运算。如果直接调用浮点运算库,可以轻松的完成任务。但这样有一个限制,就是运算过程一直以最大的精度来运算,相当浪费 MCU 的时间。我们的应用可能并不需要这么高的精度,而是需要尽快的完成运算并保留一定精度即可。在此情况下,如果我们用嵌入 ASM 做运算,可以通过减少迭代运算次数 (精度和迭代运算次数成正比)达到快速完成运算。在发动机控制等分秒必争的领域,有时候这样做是很有必要的。

【例2.8】存储器与寄存器间数据传送。 MOV AX,BUF ;BUF是变量,源操作数为直接寻址 MOV BH,[DI] ;源操作数为寄存器间接寻址 MOV DI,ES:3[SI] ;源操作数为变址寻址,使用跨段前缀 MOV BP,3[BX+SI] ;源操作数为基址加变址寻址 MOV BUFA,DL ;BUFA是一字节变量 MOV [BP],AX ;使用SS段寄存器 MOV DS:[BP],DL ;使用跨段前缀 MOV BUF,DS ;BUF是个字变量 MOV ES ,BUF 【例2.10】将一种代码转换成另一种代码。 【例2.16】更改数据段段首址。 【例2.23】带借位减运算。 【例2.48】比较数据中STR1字符串和附加段中STR2字符串是否相同。 假设两个字符串长度一样,为COUNT个字节。比较的结果存入RESULT单元, 结果为0表示相等,为-1(即FFH)表示不等。 【例2.51】用重复前缀比较两个字符串相等。 【例2.55】把数据区的数据按正、负数分开,并分别送至两个缓冲区。 【例2.56】利用子程序完成将AL低4位中的一位16进制数转换成对应的ASCII码 【例3.4】用算术运算符进行数值表达式运算。 【例3.7】用属性运算符表示类型属性。 【例3.8】下面程序段的某些语句是错误的。 【例3.9】用属性运算符定义新变量 【例3.11】分离变量类型。 【例6.5】用软中断INT 60H、发声中断服务程序INT 61H以及软中断INT 62H、 INT 63H , 实现字符串“intel 80486 DX2/66 CPU”显示、扬声器发声和变色三角形的显示功能, 定时器ICH中断作为计数器使用。 ................................................................ ................................................................ 7.1 实验步骤 在PC机上运行汇编程序必须经过以下几个步骤: (1)编辑源程序。利用文本编辑工具编辑源程序, 生成一个汇编语言源程序的纯文本文件?惚嘤镅栽闯绦虻睦┱姑?签qASM。 (2)汇编源程序。用汇编器汇编源程序生成目标代码文件,目标代码文件的扩展名 是?OBJ,汇编器还可以生成列表文件和交叉参考文件?如果源程序有语法错误行, 汇编器就不生成目标代码文件。这时,必须重新编辑源程序,修改语法错误的行。 当发现源程序中的某些行含不确定因素时,汇编器会给出警告信息,但仍按缺省处 理办法生成目标代码文件。此时,可以重新编辑源程序,消除不确定因素。 (3)连接目标程序。利用连接器连接目标代码程序和库函数代码生成可执行程序文件。 通常DOS平台上的可执行程序文件的扩展名是?EXE。一般单个? 或者与库函数连接时,如果在目标代码文件或者库中找不到所需的连接信息, 连接器就会发生错误提示信息,而不生成可执行程序文件。这时,就要重新编辑源程序, 并汇编源程序。 (4)调试可执行程序。程序的动态调试是在形成可执行程序文件后,针对可执行程序进行的。 DEBUG是简单而有效的动态调试工具,利用调试工具动态地调试程序,找出程序中的问题。 如果发现程序中有问题,那么必须重新编辑、汇编源程序。 下面以一个简单的例子说明汇编源程序的上机过程。 假定要在显示器显示如下一行信息: I am a student! 那么,其汇编源程序的过程如下: STACK SEGMENT STACK DB 200 DUP(0) STACK ENDS DATA SEGM0ENT BUF DB I am a student!$ DATA ENDS CODE SEBMENT ASSUME CS:CODE,DS:DATA,SS:STACK START: MOV AX,DATA MOV DS,AX LEA DX,BUF MOV AH,9 INT 21H MOV AH,4CH INT 21H CODE ENDS END START 第一步:编辑源程序。假定源文件名为EXAM?ASM。 第二步:汇编源程序EXAM?ASM。 A>MASM EXAM ; 此命令是调用宏汇编程序MASM对源文件EXAM?ASM进行汇编,生成目标文件EXAM?OBJ. 若汇编无错误,则进入第三步。 第三步:连接目标程序文件EXAM?OBJ。 A>LINK EXAM ; 若连接成功,则进入下一步。 第四步:运行可执行文件EXAM?EXE A>EXAM 运行结果如下: I am a student! 若未得到预期的结果,可检查EXAM?ASM文件内容,修改错误,再次汇编、连接、运行,直到满意为止。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值