Bootstrap

手把手教你学习汇编语言——从入门到起飞

专接本交流群:866965914(有什么问题欢迎进群讨论)
关于这篇博客,笔者会尽量用最简单的方式教会大家汇编语言以便应付各种考试
有什么不足的忘大佬评论或私信指出。

汇编环境安装
汇编运行调试
汇编指令

希望大家看完这些找一些样例练习一下会学的更好,这里有一些练习题希望能帮助到大家
汇编语言编程题总结

汇编语言环境安装

这里用的是Masm,相比较纯Dosbox会简单很多的
汇编语言和CodeBlock安装包 密码:dqs9

下载以后打开运行
下一步
在这里插入图片描述
安装
在这里插入图片描述
完成即可
在这里插入图片描述
安装完成后打开,进来是默认的程序框

在这里插入图片描述
汇编语言运行的话,一定要保存文件到本地才可以运行,调试的话也需要先运行一下才能调试,否则就是调试的上次运行的程序。

汇编运行调试

当我们写好以后,它会提示我们先保存在运行
在这里插入图片描述

ctrl+s保存在一个地方,记得改名字,把 * 换成名字
在这里插入图片描述

再点击运行,出现这个就可以了,这是没有屏幕输出的程序,如果有屏幕输出,还会先输出程序输出的,在输出这一行。
在这里插入图片描述

(如果到时候一闪而过,说明你的程序有问题)
下面会有提示哪一行有问题的,双击就会高亮显示那一行
(笔者这个就是在AL后面多打了一个S)

在这里插入图片描述

运行可以了,那就大概说一下调试的过程(如果要调试的话,一定要先运行一遍才可以,否则就是调试的上一次运行的代码)

调试的话,输入 T 是运行一步,你可以选择一步一步的运行,
我们输入一个T 出来的划线位置就是下一次要运行的代码
我们可以看到命令框第二个划线的 MOV AL,[0000H] 我们的AL赋值是12H 第二次AX的低四位还不是12H
当我们再输入一个T,才是12H,也就是调试出来的代码是下一次将要运行的代码。
在这里插入图片描述

也许有些时候可能会觉得一步一步调试太麻烦了,这里也有直接跳转调试的

我们之间输入一个U就会出现每一步代码所对应的数。
在这里插入图片描述

通过G 在写对应的号,就可以跳转到指定的位置
在这里插入图片描述

其他的话,可能会有更方便的,但是笔者认为这些就很够用了。

软件安装运行调试大概就是到这里了,接下来我们来简述一下基本的命令语句吧

汇编指令

先来看一下基本的结构(分号后面的都是注释的,汇编语言用分号注释)

DATAS SEGMENT	;数据段
    ;此处输入数据段代码  
DATAS ENDS
 
CODES SEGMENT	;代码段
    ASSUME CS:CODES,DS:DATAS		;数据段给DS,代码段给CS
START:			;开始代码
    MOV AX,DATAS	;需要先把DATAAX寄存器,然后再从AXDSDATA不能直接给DS
    MOV DS,AX
    ;此处输入代码段代码
    MOV AH,4CH		;结束语句
    INT 21H
    
CODES ENDS		;代码段结束
    END START	;结束代码

先来说常用的命令符号,如果大家有什么其他命令符使用的话,可以评论或者私信我,我看到会尽快给大家展示出来如何使用

MOV AL,BL
这里就是把BL的值放到AL中。

 

然后就是类似于C语言的函数
这个函数就是起个名字加个分号
汇编语言的函数没有结束的地方,一般如果需要结束的加,就要加一个跳转到其他地方
如果没有跳转,他就会一直运行到下面

DATA SEGMENT 
A DB 12H	;定义两个变量
B DB 24H
DATA ENDS 
CODES SEGMENT 
	ASSUME DS:DATA,CS:CODES
START:
	MOV AX,DATA
	MOV DS,AX
	
	JMP EXIT	;这里就是直接跳转到EXIT  JMP就是跳转的方法
	
	MOV AL,A	;A->AL
	MOV BL,B	;B->BL
	MOV A,BL	;BL->A
	MOV B,AL	;AL->B
	 
	 
EXIT:
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START


当然还有很多特别的JMP 也就是一些带标志位的 就是标志寄存器里面的六个状态位

1、进位标志CF(Carry Flag)
进位标志CF主要用来反映运算是否产生进位或借位。如果运算结果的最高位产生了一个进位或借位,那么,其值为1,否则其值为0使用该标志位的情况有:多字(字节)数的加减运算,无符号数的大小比较运算,移位操作,字(字节)之间移位,专门改变CF值的指令等。

2、奇偶标志PF(Parity Flag)

奇偶标志PF用于反映运算结果中“1”的个数的奇偶性。如果“1”的个数为偶数,则PF的值为1,否则其值为0。

利用PF可进行奇偶校验检查,或产生奇偶校验位。在数据传送过程中,为了提供传送的可靠性,如果采用奇偶校验的方法,就可使用该标志位。

3、辅助进位标志AF(Auxiliary Carry Flag)
在发生下列情况时,辅助进位标志AF的值被置为1,否则其值为0:

(1)、在字操作时,发生低字节向高字节进位或借位时;
(2)、在字节操作时,发生低4位向高4位进位或借位时。

对以上6个运算结果标志位,在一般编程情况下,标志位CFZFSFOF的使用频率较高,而标志位PFAF的使用频率较低。

4、零标志ZF(Zero Flag)
零标志ZF用来反映运算结果是否为0。如果运算结果为0,则其值为1,否则其值为0。在判断运算结果是否为0时,可使用此标志位。

5、符号标志SF(Sign Flag)

符号标志SF用来反映运算结果的符号位,它与运算结果的最高位相同。
在微机系统中,有符号数采用补码表示法,所以,SF也就反映运算结果的正负号。运算结果为正数时,SF的值为0,否则其值为16、溢出标志OF(Overflow Flag)

溢出标志OF用于反映有符号数加减运算所得结果是否溢出。如果运算结果超过当前运算位数所能表示的范围,则称为溢出,
OF的值被置为1,否则,OF的值被清为0。 
(有些时候,有些问题会问你是不是溢出了,这里有个巧计的方法,负数加负数是正数,正数加正数是负数,如果出现这种情况就是溢出了)

然后衍生出来的就是几个条件跳转指令
一般情况下,条件跳转上面要跟一些影响标志寄存器的命令


JE   ;等于则跳转
JNE  ;不等于则跳转
 
JZ   ;0 则跳转
JNZ  ;不为 0 则跳转
 
JS   ;为负则跳转
JNS  ;不为负则跳转
 
JC   ;进位则跳转
JNC  ;不进位则跳转
 
JO   ;溢出则跳转
JNO  ;不溢出则跳转
 
JA   ;无符号大于则跳转
JNA  ;无符号不大于则跳转
JAE  ;无符号大于等于则跳转
JNAE ;无符号不大于等于则跳转
 
JG   ;有符号大于则跳转
JNG  ;有符号不大于则跳转
JGE  ;有符号大于等于则跳转
JNGE ;有符号不大于等于则跳转
 
JB   ;无符号小于则跳转
JNB  ;无符号不小于则跳转
JBE  ;无符号小于等于则跳转
JNBE ;无符号不小于等于则跳转
 
JL   ;有符号小于则跳转
JNL  ;有符号不小于则跳转
JLE  ;有符号小于等于则跳转
JNLE ;有符号不小于等于则跳转
 
JP   ;奇偶位置位则跳转
JNP  ;奇偶位清除则跳转
JPE  ;奇偶位相等则跳转
JPO  ;奇偶位不等则跳转

说完跳转类的指令,接下来我们看一看左移右移指令
左移这种指令左移一位就是二进制左移一位,也就是乘2的操作。

SHL(Shift Left)SAL(Shift Arithmetic Left): 每位左移, 低位补 0,  高位进 CF
SHR(Shift Right)     : 每位右移, 低位进 CF, 高位补 0
SAR(Shift Arithmetic Right)     : 每位右移, 低位进 CF, 高位不变(也就是高位复制到第二位)

使用的时候就是 
SHL AL,1
左移一位
如果移动的位数大于1位,就要放到CX

循环左移右移

;ROL(Rotate Left): 循环左移, 高位到低位并送 CF
;ROR(Rotate Right): 循环右移, 低位到高位并送 CF
;RCL(Rotate through Carry Left): 循环左移, 进位值(CF)到低位, 高位进 CF
;RCR(Rotate through Carry Right): 循环右移, 进位值(CF)到高位, 低位进 CF

使用的时候就是 
ROL AL,1
循环左移一位
如果移动的位数大于1位,就要放到CX

然后就是加减乘除

加法add和adc、inc
ADD AL,BL
ALBL加起来放到AL

ADC的话就是ADD的运算在家一个CF状态位的值,

INC AL
AL1


减法sub和sbb、dec
SUB 对应ADD
SBB 对应ADC
DEC 对应INC
用法都是一样的,就是一个是加一个是减

乘法mul和imul
MUL是无符号乘法
MUL 8位的   就是AL乘这个数放到AL 高位放到AH
MUL 16位的   就是AX乘这个数放到AX中	高位放到DX

除法div和idiv
DIV是无符号除法
DIV 8位的   就是 AX除这个数,商放AL  余数放AH
DIV16位的   就是(DX:AX)除这个数,商放AX  余数放DX

异或运算XOR

XOR AL,BL
ALBL异或运算放入AL

与运算AND   或运算OR都是一样的

然后就是CMPTEST
CMP 就是对应的减法,但是这个不会影响AL的值,他只会影响状态标志位
TEST 就是AND的用法,也是不会影响AL,只影响状态标志位

最后就是DOS功能的输入输出

字符输入输出
DATA SEGMENT 
	 
DATA ENDS 

CODES SEGMENT 
	ASSUME DS:DATA,CS:CODES
START:
	MOV AX,DATA
	MOV DS,AX
	
	MOV AH,01H	 ;键盘输入的时候,给AH  1
	INT 21H		 ;然后INT 21H调用,默认输入到ALMOV DL,AL	 ;CMD窗口输出的时候,要把输出的放到DLMOV AH,02H	 ;AH  2
	INT 21H
	
	 
	 
EXIT:
   		MOV AH,4CH
        INT 21H
CODES ENDS
    END START
字符串输入输出
DATA SEGMENT 
	 BUF DB 20 DUP('$')
	 BUFF DB 'Hello World!$'
DATA ENDS 

CODES SEGMENT 
	ASSUME DS:DATA,CS:CODES
START:
	MOV AX,DATA
	MOV DS,AX
	
	MOV DX,OFFSET BUF	;把偏移地址给DX,也可以用 LEA DX,BUF  二者皆可
	MOV AH,0AH	 ;键盘输入的时候,给AH  10
	INT 21H		 ;然后INT 21H调用,默认输入到BUFMOV DX,OFFSET BUFF	 ;CMD窗口输出的时候,要把输出偏移地址放到DXMOV AH,09H	 ;AH  2
	INT 21H
	
	 
	 
EXIT:
   		MOV AH,4CH
        INT 21H
CODES ENDS
    END START
;