汇编语言:知识点拾遗
2016-12-18 17:33
225 查看
汇编语言:知识点拾遗
前言
读王爽的书已经有一段时间了,马上就要学习有关“中断”的知识了。在继续学习之前,我想把一些我感觉比较有意思的小细节,小技巧总结一下。文章不长,如果以后有新的收获,我会把这一系列继续写下去。大小写字转换的技巧
一般来说,要想实现大小写字母的转换,有两种基本思路。根据大小写字母在ascii表中的相对位置进行转换
根据字母在字母表中相对于首字母a的位置进行转换
第一种思路:
如果字母为大写字母,小写字母 = 大写字母 + 20H
如果字母为小写字母,大写字母 = 小写字母 - 20H
第二种思路:
如果字母为大写字母,小写字母 = ‘a’ + 大写字母 - ‘A’
如果字母为小写字母,大写字母 = ‘A’ + 小写字母 - ‘a’
王爽的书中有提供了令一种方法:
假设当前字母在寄存器AL中
如果AL为大写字母,则
and al,11011111B
如果AL为小写字母,则
or al,00100000B
此时AL中即为所要转换的结果。
为什么可以这样做呢?我下面给出一张表格,供大家验证。
大写 | 十六进制 | 二进制 | 小写 | 十六进制 | 二进制 |
---|---|---|---|---|---|
A | 41H | 01000001 | a | 61H | 01100001 |
B | 42H | 01000010 | b | 62H | 01100010 |
C | 43H | 01000011 | c | 63H | 01100011 |
D | 44H | 01000100 | d | 64H | 01100100 |
E | 45H | 01000101 | e | 65H | 01100101 |
F | 46H | 01000110 | f | 66H | 01100110 |
JMP、CALL、RET指令的机制
以下用s表示标号jmp short s——依据位移修改IP进行段内短转移(8位位移)
jmp near ptr s——依据位移修改IP进行段内近转移(16位位移)
jmp far ptr s——段间远转移,使(CS) = s的段地址,(IP) = s的偏移地址
jmp 16位reg——使(IP) = (reg)
jmp word ptr 内存单元地址——使(IP) = (内存单元地址)
jmp dword ptr 内存单元地址——使(CS) = (内存单元地址+2),(IP) = (内存单元地址)
详细内容见原书。
我们可以用汇编语言(尽管不符合语法)去理解ret和call指令
ret——相当于
pop IP
retf——相对于先
pop IP,然后
pop CS
call s——相当于先
push IP,然后
jmp near ptr s
call far ptr s——相当于先
push CS,再
push IP,最后
jmp far ptr s
call 16位reg——相当于
push IP,然后
jmp reg(16位)
call word ptr 内存单元地址——相当于
push IP,然后
jmp word ptr 内存单元地址
call dword ptr 内存单元地址——相当于先
push CS,再
push IP,最后
jmp dword ptr 内存单元地址
由于call与ret常常配合使用,所以之前我以为这两条指令必须成对出现(在设计子程序的时候)。汇编语言是相当自由的语言,当然没有这种约束,这些指令你想怎么用,你就怎么用,只不过它们的配合使用是一种“套路”罢了。
如果不熟悉call,ret的执行原理,在设计子程序的堆栈传参时,就会很难理解。
我在课堂上学习这两条指令的时候,老师完全没说堆栈的事,之后我发现有一个实验(输出一个集合的所有子集)是要用递归的技巧的,我当时就要骂人了,老师当时堆栈传参讲的不清不楚(说难听点,讲了和没讲是一样的),果断放弃这个选题,选了一个更简单的实验,但这样怎么体现出我认真的学习态度呢?(不要脸)
后来学习了王爽的书,弄懂了这些原理,堆栈传参就很好理解了。
最后补充一点:
ret n——相当于
pop IP,然后
add sp,n
C语言中局部变量也在堆栈中存放。
标志位DF与串处理指令
这部分老师在课堂上是不讲的(不知道其他学校是怎么样的)。其实这部分很简单。方向标志位DF
DF = 1,每次操作后
inc si, inc di
DF = 2,每次操作后
dec si, dec di
cld指令使DF=0,
std指令DF =1
下面用汇编指令(不符合语法)来理解下面两条指令
movsb
功能:mov es:[di], byte ptr ds:[si] ;如果DF = 0 inc si inc di ;如果DF = 1 dec si dec di
movsw
功能:mov es:[di], word ptr ds:[si] ;如果DF = 0 add si,2 add di,2 ;如果DF = 1 sub si,2 sub di,2
rep指令
rep指令常常和以上两条指令配合使用。举个例子:rep movsb相当于
s: movsb loop s ;根据CX决定循环次数
小结
串传送指令的注意点传送的初始位置:ds : si
传送的目的位置:es : di
传送的长度: CX
传递的方向: 标志为DF
其他注意事项
由于篇幅原因(其实就是懒得再写下去了),还有一些注意点就不详细讨论了。b0ed
比如:
- 除法指令的溢出问题
- 80X25彩色字符模式的显示缓冲区
总结
汇编语言是一门相当自由的语言,只要你有耐心,你可以用它完成好多事情。这种感觉是在学习王爽的教材中体会得到。在此之前,我只是通过学校课堂大概了解了一下汇编语言,我甚至不知道数据段,代码段,堆栈段是可以通过自己修改段寄存器来“定义”的(就是蠢,没别的解释)。但这种自由也带来一种坏处,就是代码的可读性较差,核心代码往往被其他操作掩盖(比如中间值传递,传参,保护寄存器),因此看似很长的代码,实际实现的功能很简单(这让我怎么显摆),甚至昨天刚写的代码,第二天居然读不懂了(好吧,我只是因为懒,没写注释,但不管怎么说,汇编就是难读!)。
但不管怎么说汇编还是很有用的。下面就用王爽书中的实验11——编写子程序,结束这篇博文。(我怎么还没写注释!反正没有老师看,偷个懒啦)
assume cs:codesg datasg segment db 'Beginner`s All-purpose Symbolic Instruction Code.',0 datasg ends codesg segment main: mov ax,datasg mov ds,ax mov si,0 call letterc mov ax,4c00h int 21h ;----------------------------------------------------------- ;proc_name: letterc ;function: translate uppercase into lowercase in a string which ends with digit 0 ;interface: ds:si points to the first address of the string letterc: push ax push si letterc_s: mov al,[si] cmp al,'a' jb letterc_next cmp al,'z' ja letterc_next and al,11011111b mov [si],al letterc_next: inc si cmp al,0 je letterc_out jmp short letterc_s letterc_out: pop si pop ax ret ;---------------------------------------------------------- codesg ends end main
相关文章推荐
- 汇编语言学习知识点1
- 北京自考北大上机汇编语言知识点总结
- 北京自考北大上机汇编语言知识点总结(二)
- C语言知识点拾遗
- 汇编语言-读书知识点记录
- 汇编语言MASM考试知识点小结!
- 汇编语言第三版(王爽著)第一章知识点整理
- 汇编语言知识点总结
- 国嵌ARM 上学期专题3之汇编语言玩得转 常见问题解决方案和知识点总结
- 汇编语言 知识点回顾
- 汇编语言-读书知识点记录2
- 【复习拾遗】 汇编语言
- 汇编语言小知识点
- 汇编语言 标志位介绍
- 非压缩BCD码转压缩BCD码汇编语言
- C语言知识点总结 -思维导图
- 汇编语言:输入两个数,不大于30,有提示,比较两个数字,如果相等,计算和,如果不相等,计算平均值,并且都要以2进制的格式输出,按照升序输出,计算两个数字各占和的百分比,并且按照“%”的格式输出。
- 汇编语言的标志寄存器和条件转移指令
- 汇编语言第二章节检测2-2
- 想学好OC, 需要的C语言必备知识点