ASM32 1 配置asm32环境
基本运行环境打开VS2019,新建C++空项目
生成依赖项右键项目名称,依次选择生成依赖项、生成自定义
在弹出的窗口中勾选masm,点击确定
添加汇编源文件右键“源文件“文件夹,依次选择添加、新建项
在弹出的窗口中选择C++文件(.cpp),注意名称中的后缀名要改为.asm
右键源文件,选择属性,配置如下
至此汇编语言的基本运行环境配置完毕
添加Irvine32链接库Irvine32 链接库提供了很多简单的输入输岀接口,因此有必要添加Irvine32链接库,方便后续编程
下载并解压Irvine32 链接库文件下载地址Assembly Language for x86 Processors (asmirvine.com)
记住解压的路径,配置VS2019需要用到
配置VS2019右键项目,选择属性,打开属性页面板
选择“Microsoft Macro Assembler”→“General” ,在Include Paths一栏输入Irvine32文件解压的路径
选择“链接器”→“常规”→“附加库目录”,输入 Irvine32文件解压的路径
选择“链接器”→“输入”→ ...
ASM16 25 串操作类指令
串操作类指令
串操作指令是8086指令系统中比较独特的一类指令,采用比较特殊的数据串寻址方式,在操作主存连续区域的数据时,特别好用、因而常用
重要掌握:MOVS STOS LODS CMPS SCAS REP
一般了解:REPZ/REPE REPNZ/REPNE
串数据类型
串操作指令的操作数是主存中连续存放的数据串(String)——即在连续的主存区域中,字节或字的序列
串操作指令的操作对象是以字(W)为单位的字串,或是以字节(B)为单位的字节串
串存储STOS(store string)
把AL或AX数据传送至目的地址
串读取LODS(load string)
把指定主存单元的数据传送给AL或AX
串比较CMPS(compare string)
将主存中的源操作数减去至目的操作数,以便设置标志,进而比较两操作数之间的关系
串扫描SCAS(scan string)
将AL/AX减去至目的操作数,以便设置标志,进而比较AL/AX与操作数之间的关系
重复前缀指令(repeat)
串操作指令执行一次,仅对数据串中的一个 ...
ASM16 23-24 位操作类指令
位操作类指令
位操作类指令以二进制位为基本单位进行数据的操作;这是一类常用的指令,都应该特别掌握
注意这些指令对标志位的影响
逻辑运算指令 AND OR XOR NOT TEST
移位指令 SHL SHR SAR
循环移位指令 ROL ROR RCL RCR
逻辑运算指令12345mov ax,-1and ax,8000h ;某位清0or ax,1 ;某位置1xor ax,0fh ;某位取反not ax
运行结果
移位指令
SHL(逻辑左移(无符号))
SHR(逻辑右移(无符号))
SAL(算术左移(有符号))(同SHL)
SAR(算术右移(有符号))
1234mov ax,0fhsar ax,1shl ax,1shr ax,1
运行结果(若最高位为0则算术右移后也补0)
12mov ax,0ffffhsar ax,1
若最高位为1则算术右移后也补1
循环移位指令(rotate)
将操作数从另一端溢移出的位返回到另一端形成循环,分成不带进位和带进位,分别具有左移或右移操作
循环移位指令对标志的影响
按照指令功能设置进位标 ...
ASM16 22-23 处理机控制类指令
处理机控制类指令
这些指令在特定的情况下,必须使用
对标志位进行设置的指令
CLC STC CMC
CLD STD
CLI STI
对CPU状态进行控制的指令
NOP CS:SS:DS:ES:
LOCK HLT ESC WAIT
进位标志操作指令
用于任意设置进位标志
123clc ;复位进位标志:cf=0stc ;置位进位标志:cf=1cmc ;求反进位标志:cf=~cf
方向标志操作指令
串操作指令中,需要使用
12cld ;复位方向标志:df=0std ;置位方向标志:df=1
中断标志操作指令
在编写中断服务程序时,需要控制可屏蔽中断的允许和禁止
12cli ;复位中断标志:if=0sti ;置位中断标志:if=1
空操作指令
NOP不执行任何操作,但占用一个字节存储单元,空耗一个指令执行周期
NOP常用于程序调试
在需要预留指令空间时用NOP填充
代码空间多余时也可以用NOP填充
还可以用NOP实现软件延时
事实上,NOP和XCHG AX,AX的指令代码一样,都是90H
12345678910111 ...
ASM16 21 函数补充和中断指令
函数补充123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103MyStack segment stack db 256 dup(?)MyStack endsMyData segmentMY_MSG1 db "Hello World1!",0dh,0ah,'$'MY_MSG2 db "Hello World2!",0dh,0ah,'$'MyData endsMyCode2 segment call far ptr MY_SUBMY_SUB: push bp mov bp,sp ;保存栈底 mov ax,[bp+6] su ...
ASM16 20 花指令和函数调用
花指令1234567891011121314151617181920212223242526MyStack segment stack db 256 dup(?)MyStack endsMyData segmentMY_MSG db "Hello World!",0dh,0ah,'$'MyData endsMyCode segmentMAIN: mov ax,MyData mov ds,ax mov es,ax jmp LABEL1 db 0b8h ;花指令LABEL1: mov dx,offset MY_MSG mov ah,09h int 21h mov ax,4c00h int 21hMyCode endsend MAIN
这种程序可以正常运行,但是反汇编代码时会分析错误,因为有数据的干扰
正常运行
编译器会把b8当成代码进行分析,从而导致后面分析处于出来的代码都是错的
但是如果找到花指令并从正确的地方开始分析,则分析出来的代码是正确的
解决方法是找到花指令并nop
...
ASM16 19 通讯录
通讯录123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177MyStack segment stack db 256 dup(?)MyStack endsMyData segmentMENU1 db & ...
ASM16 18 循环语句
简单的do-while,先循环再判断
123456789101112131415161718192021222324252627MyStack segment stack db 256 dup(?)MyStack endsMyData segment MSG1 db "Hello World!",0dh,0ah,'$'MyData endsMyCode segment MAIN: mov ax,MyData mov ds,ax mov es,ax ;循环 do-while mov cx,3LOOP1: inc ax dec cx jnz LOOP1 mov ax,4c00h int 21hMyCode endsend MAIN
常规的while写法,先判断再循环
12345678910111213141516171819202122232 ...
ASM16 17 判断语句
CPU采用流水线设计,跳转时的运行周期更长,则写代码时要尽量减少跳转(跳转断流水线)
流水线设计思想设计的处理器是五级流水处理器,取指,译码,执行,访存,回写。(1)取指: 取出指令存储器中的指令,PC值递增,准备取下一条指令。(2)译码:对指令进行译码,依据译码结果,从32个通用寄存器中取出源操作数,有的 指令要求两个源操作数都是寄存器的值,比如or指令,有的指令要求其中一 个源操作数是指令中立即数的扩展,比如ori指令,所以这里有两个复用器, 用于依据指令要求,确定参与运算的操作数,最终确定的两个操作数会送到执 行阶段。(3)执行:依据译码阶段送入的源操作数、操作码,进行运算,对于ori指令而言, 就是进行逻辑“或”运算,运算结果传递到访存阶段。(4)访存:对于ori指令,在访存阶段没有任何操作,直接将运算结果向下传递到回写阶 段。(5)回写:将运算结果保存到目的寄存器。
在程序指令依次执行的情况下,CPU流水线条数和CPU性能成正比。但当程序指令出现跳转或分支结构时就要另当别论了。比如当指令是jmp (无条件的转移到指令指定的地址去执行从该地址开始的命令)指令时,jmp指令会直接 ...
ASM16 16 BCD码和控制转移类指令
BCD码
二进制编码的十进制数:一位十进制数用4位二进制编码来表示
8086支持压缩BCD码和非压缩BCD码的调整运算
真值
8
64
二进制编码
08H
40H
压缩BCD码
08H
64H
非压缩BCD码
08H
0604H
压缩BCD码加、减调整指令
使用DAA或DAS指令前,应先执行以AL为目的操作数的加法或减法指令
非压缩BCD码加、减调整指令
使用AAA或AAS指令前应先执行以AL为目的操作数的加法或减法指令
AAA和AAS指令在调整中产生了进位或借位,则AH要加上进位或减去借位,同时CF=AF=1,否则CF=AF=0;它们对其他标志无定义
非压缩BCD码乘、除调整指令
AAM指令跟在字节乘MUL之后,将乘积调整位非压缩BCD码
AAD指令跟在字节除DIV之前,先将非压缩BCD码的被除数调整为二进制数
AAM和AAD指令根据结果设置SF、ZF和PF,但对OF、CF和AF无定义
123456789mov al,19h ;bcd压缩码 19+1==>20 inc al ;16运算结果调整 ...