大家好,我是ErikTse,我又来更新学科知识了,还有几天就要考8086汇编程序设计,现在开始一个预习。
因为只学了半天,所以很多东西理解并不到位,大家看个热闹好了~主要是自己记录一下。
一、INT 21H中断
INT 21H
是指中断向量地址21H,用于DOS中的系统功能。具体是什么功能取决于AH
标志位。
二、AH寄存器的标志
AH
寄存器在输入输出和程序结束中十分关键,它用于定义INT 21H
的中断含义。
MOV AH, 4CH
相当于C语言中的return 0;
,用于表示程序结束。-
MOV AH, 01H
用于输入一个字符,存储到AL
,相当于C语言中的AL = getchar()
,这里AL
是AX
寄存器的低8位,AH
是高八位。 -
MOV AH, 0AH
用于输入一个字符串到[DX],注意具体的输入逻辑是,将字符串输入到[DX + 2],将字符串长度保存到[DX + 1]位置,[DX]是用于定义的缓冲区长度,稍后会有代码介绍。 -
MOV AH, 02H
用于输出[DL]中的字符。 -
MOV AH, 09H
用于输出[DX]中的字符串内容,如果是字符串就一直输出直到遇到'$',相当于C语言中的'\0'。
在这些语句之后接上INT 21H
即可实现调用DOS功能。
例如输出一个字符#:
MOV DL, '#'
MOV AH, 02H
INT 21H
三、循环语句
循环语句一般默认用CX
寄存器作为循环变量,利用JNZ
指令和标记进行跳转,格式一般为:
MOV CH, 00H;将CX高位CH置零
MOV CL, AL;将AL内容送到CL,作为循环变量
;循环CX次
LP: ;LP标记,有点goto语句内味
;循环内要做的事儿
DEC CX;CX --
JNZ LP;Jump if Not Zero,判断的是CX
当然你也可以通过CMP指令来指定JNZ所判断的寄存器,这个在后面双重循环中可以看到。
四、输入输出一个字符
我们来实现一个简单的程序,输入一个一位数整数n,输出n个字符'$'。
DATA SEGMENT
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MOV AX, DATA
MOV DS, AX
;以上为固定语句,意思是将DATA段的地址送到DS寄存器
MOV AH, 01H;输入一个字符到[AL]
INT 21H;中断
;注意此时AL为一个字符,需要转换为数字
SUB AL, 30H;将AL减去48(30H),参考ASCII表
MOV CH, 00H;将CX高位CH置零
MOV CL, AL;将AL内容送到CL,作为循环变量
LP:
;在这里输出字符$
MOV DL, '$';将字符$送到DL寄存器
MOV AH, 02H;02H的作用是输出一个字符
INT 21H
DEC CX;CX --
JNZ LP;Jump if Not Zero,判断的是CX
;以下为固定语句
MOV AH, 4CH
INT 21H
CODE ENDS
END START
咱们再写一个双重循环,输出15行16列,10H~FFH所有字符。
DATA SEGMENT
new_row DB 0DH, 0AH, '$'
chr DB 10H
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MOV AX, DATA
MOV DS, AX
MOV CX, 0FH;CX = 15
LP1:
MOV BX, 10H;BX = 16
LP2:
MOV DL, [chr]
MOV AH, 02H
INT 21H
INC [chr];每输出一次就[ch]+1
;输出一个空格
MOV DL, ' '
MOV AH, 02H
INT 21H
DEC BX;
CMP BX, 00H
JNZ LP2
;内层循环结束,输出换行
LEA DX, new_row
MOV AH, 09H
INT 21H
DEC CX
CMP CX, 00H
JNZ LP1
MOV AH, 4CH
INT 21H
CODE ENDS
END START
五、例题
这里写一个例题,来将一个8位二进制数转换为2位十六进制数:
DATA SEGMENT
ARR DB 9, ?, 9 DUP('$')
NEW_LINE DB 0DH, 0AH, '$'
NUM DB 0, 0
CHR DB '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MOV AX, DATA
MOV DS, AX
;将字符串输入进ARR数组
LEA DX, ARR
MOV AH, 0AH
INT 21H
LEA DX, NEW_LINE
MOV AH, 09H
INT 21H
MOV CX, 2
LEA SI, ARR + 2;将输入的字符串首地址给SI
LP1:
MOV AL, [SI]
SHL NUM, 1
SUB AL, 30H
ADD NUM, AL
INC SI
INC CX
CMP CX, 5
JNA LP1
;处理得到[NUM + 1]
LP2:
MOV AL, [SI]
SHL NUM + 1, 1
SUB AL, 30H
ADD NUM + 1, AL
INC SI
INC CX
CMP CX, 9
JNA LP2
;输出CHR[NUM + 0]
LEA DI, CHR;将CHR的地址给DI
MOV AH, 00H;将AX高8位置零
MOV AL, NUM;将NUM内容给AL
MOV SI, AX;将AX赋值给SI作为偏移量
ADD DI, SI;计算地址
MOV DL, [DI];将DI值给DL
MOV AH, 02H;打印输出
INT 21H
;输出CHR[NUM + 1]
LEA DI, CHR;将CHR的地址给DI
MOV AH, 00H;将AX高8位置零
MOV AL, NUM + 1;将NUM内容给AL
MOV SI, AX;将AX赋值给SI作为偏移量
ADD DI, SI;计算地址
MOV DL, [DI];将DI值给DL
MOV AH, 02H;打印输出
INT 21H
MOV DL, 'H'
MOV AH, 02H
INT 21H
MOV AH, 4CH
INT 21H
CODE ENDS
END START
Comments NOTHING