SHU汇编程序设计常见考点、易错点总结与综合实例、汇编学习资源

SHU汇编程序设计常见考点、易错点总结与综合实例、汇编学习资源

今天刚刚考完汇编,决定将这个学期记录的一些要点进行总结与归纳,希望给需要的朋友一些帮助。

读完后,自己再加以练习,考试肯定不会挂(😀)

文章内容主要包含以下几部分:

  1. 常见考点
  2. 常见易错点
  3. 综合实例
  4. 友情资源放送

一、常见考点

1、寻址方式

8086cpu寻址方式主要有7种,分别为:

1、立即寻址:MOV AL,5
2、直接寻址:MOV AX,[2000H]
3、寄存器寻址:MOV AX,BX
4、寄存器间接寻址:MOV AX,[BX]
5、寄存器相对寻址:MOV AX,[BX+2000H]
6、基址变址寻址:MOV AX,[BX+SI]         
7、相对基址变址寻址:MOV AX,[BX+SI+2000H] ;使用基址寄存器与变址寄存器

几者的主要区别在于使用的寄存器立即数

2、移位

(1)移位重点要掌握算数右移与逻辑右移的区别:算数右移时,最高有效位不变。(可以将其理解成,操作有符号数,算数右移时,其符号位仍不变,只是数据大小改变。)

(2)逻辑左移与算数左移操作完全相同,最高位移入CF标志位,最低位补0。

(3)值得注意的是,在考试的时候要注意题目给的数据格式,例如题目给的是:

AX = 4CH,CL=4,问其SAL CL之后,AX等于多少?

这时你要注意到题目给的AX是16位,为2个字节,而其左边一个字节的内容没有写出来(都为0),所以做题的时候需要把左边的8个0补全之后进行移位操作,这样不会出错。

(4)逻辑移位针对的是无符号数,而算数移位针对的是有符号数。

3、乘除运算

乘除运算需要注意的地方有三个:

(1)两数相乘时,两者的位数需要相同,例如AL只能和BL相乘,而不能和BX相乘。两个8位相乘,结果保存在AX中;两个16位相乘,结果高位保存在DX中,低位保存在AX中。

(2)两数相除时,被除数的位数为除数的两倍。即除以一个8位字节数据时,被除数需要是16位。此时余数保存在AH中,商保存在AL中。被除数为32位时,余数保存在DX中,商保存在AX中。

(3)MUL和DIV针对无符号数,IMUL和IDIV针对有符号数。

4、加减操作

加减操作需要注意的地方在于进行两个数据的加减时,注意进/借位。

比如两个低字节相加,可能产生进位,这时需要高字节需要加上可能的进位:

ADD AL,BL
ADC AX,0 ;ADC表示加0之后再加CF标志位,也即只加CF标志位,即可能产生的进位。

5、取址操作

取址操作常与LOOP循环等结合用于编程题中一个字符串或者数组的遍历。

可以使用两种方式:

假设数据段已经定义了字符串STRING
1、MOV AX,OFFSET STRING
2、LEA AX,STRING

两者等价。但是OFFSET只能与简单的符号地址相连,而不能和诸如STRING[SI]等复杂操作数相连。

6、出入栈

栈在一些初学汇编语言时用的不多。作者用到栈这一数据结构主要是在考试大题里,用来保护现场(后面会讲到)。

这块需要注意的主要是出入栈时,SP指针的变化。

1、PUSH入栈:SP = SP - 2
2、POP出栈: SP = SP + 2

注:PUSH,POP都不改变标志位。

7、中断

中断这部分主要需要掌握:

(1)中断向量的定义(笔者考试没答出来):

在实模式下,将中断服务程序的入口地址称为中断向量。

(2)中断向量表的定义、位置,大小,以及如何找到中断向量所在位置。

1、存放256个中断向量的内存区域称为中断向量表。
2、中断向量表位于内存地址00000H ~ 003FFH,共1KB(256*4B,256个中断向量,每个占4字节)。
3、对于中断号n,中断向量所在地址为4n ~ 4n+3。例如,0号中断的向量位于地址00000H,1号中断的向量位于地址00004H,等等。

(3)设置与获取中断向量(一般在选择题)

1、设置中断向量:AH=25H(INT 21H)
2、获取中断向量:AH=35H(INT 21H)

8、标志位

标志位一般是通过执行指令来改变的,需要在平时使用常见指令,如MOV,ADD等这些操作时,记住他们对标志位的影响。由于指令的数量比较多,也比较难记全,所以需要一些方法,比如将常见的同一类型的指令记在一起:

1、INC、DEC,JMP,LOOP,CALL,MOV,LEA,PUSH和POP对标志位无影响

9、常见的字符的ASCII码

这部分必须要掌握,因为编程题里一般都会涉及到字母、数字判断和统计等,如果不掌握常见字符的ASCII码,那么便很难下笔。

常用字符的ASCII码如下:

  数字'0'~'9':30H~39H
  字母'A'~'Z':41H~5AH
  字母'a'~'z':61H~7AH
  空格:20H 
  回车CR:0DH
  换行LF:0AH

注意回车与换行的差别: CR用来控制光标回到当前行的最左端;LF用来移动光标到下一行,而所在列不变。

10、IO端口

8086的端口有64K个(2^16)个。寻址方式有两种:

直接寻址:只用于寻址00H ~ FFH前256个端口,操作数i8表示端口号

间接寻址:可用于寻址全部64K个端口,DX寄存器的值就是端口号

对大于FFH的端口只能采用间接寻址方式。

常用指令如下:

;输入输出一个字节,利用AL,若为字,则利用AX。
;例:向300H端口输入/出一个字节
	mov al,bvar	;bvar是字节变量
	mov dx,300h
	in  dx,al;输入
	out dx,al;输出
;此处端口号大于256,只能采用间接寻址。

注:IN,OUT指令对标志位无影响。

11、输入输出

输入输出这部分在编程大题里属于必考部分(笔者今天最后一道24分大题就用到了)。

这部分重点需要掌握四个部分:

1、从键盘上输入一个字符

参数:

AH = 01H AL = 输入字符后,字符的ASCII 码值

MOV AH ,01H
INT 21H

2 、向显示器输出一个字符

参数:

AH = 02H, DL = '欲输出的字符ASCII码‘

示例:

MOV DL ,'C'
MOV AH , 02H
INT 21H

注:在题目里面,一般将寄存器内的值输送到DL中。

3 、 向显示器输出一个字符串

参数:

AH = 09H,DS = 欲输出字符串的段地址 DX = 欲输出字符串的偏移地址

MOV  DX , OFFSET STRING ;或者LEA DX,STRING
MOV  AH, 09H;
INT 21H

此处需特别注意,字符串必须以’$'字符结尾。

4、输入一段内容(利用缓冲区)

这部分主要包含两个部分:缓冲区与输入。

<1>缓冲区

8086中缓冲区的设置方法如下:

在数据段定义一个指定长度的内存区域。其示例格式如下:

BUFFER DB 128,?,128 dup(?)

其中,BUFFER为缓冲区的名字,DB为缓冲区中数据的数据类型,第一个128表示缓冲区的指定长度(可调),问号表示缓冲区实际输入内容的长度,第二个128 dup表示在内存中开拓128字节的空间,与第一个128对应。

这里的一个技巧在于,在大题里,定义缓冲区后,可以将BUFFER[1],即缓冲区实际内容长度,送入到CX中,对缓冲区内容进行遍历。

注意:缓冲区实际内容从BUFFER[2]开始。

<2>输入一段内容

输入一段内容参数和前面输出字符串基本相同,不同的地方在于AH的值设定不同,此处为0AH

参数:

AH = 0AH,DS = 欲输出字符串的段地址 DX = 欲输出字符串的偏移地址

MOV  DX , OFFSET STRING ;或者LEA DX,STRING
MOV  AH, 09H;
INT 21H

二、常见易错点

1、汇编语言中,数据不能以字母开头。

例:

A000H应记为0A000H

2、8086CPU所有寄存器为16位,为了兼容之前8位cpu,一些寄存器可以拆分为两个8位(高8位H,低8位L)使用,例如:

AX寄存器可以拆分成AH和AL分开使用。但是一些寄存器不能拆分为两个8位来使用,例如:SI与DI。

3、若使用BP寄存器,则段地址默认在SS中。且寻址时BX、BP,SI、DI两两二选一搭配使用。

4、PUSH和POP指令操作数据类型为:

5、只修改IP为段内转移,同时修改CS和IP为段间转移。

三、综合实例

综合实例这部分我主要给出两个实例,一小一大,并提供一些注释,供大家参考。

1、实现双字同时左移四位

此处示例为:(DX,AX)双字逻辑左移4位

分析:这里主要需要注意AH高四位的移动。具体代码如下:

MOV CL,4  ;设置移位次数
SHL DX,CL 
MOV BL,AH
SHL AX,CL ;AX左移4位
SHR BL,CL
OR DL,BL ;第3、5、6行的作用是将AH的高四位移动到DL的低4位

2、输入一段字符串,其以$字符结尾,统计其中数字、大写字母、小写字母、其他字符的个数,并输出至屏幕,要求使用子程序。

分析:这里我把题目写的很简洁,但是其中包含了许多的知识点(输入输出,字符计数,子程序等),属于综合题。

具体代码如下:

;默认采用ML6.11汇编程序
DATAS SEGMENT
	string db 80,?,80 dup(?)  ;设定缓冲区
    up_letter db 0            ;大写字母计数
    down_letter db 0          ;小写字母计数
    digit db 0                ;数字计数
    other dw 0                ;其他字符计数
    input db 'input a line:$'   ;输入提示
    up_letter_count db 0dh,0ah,'UPletter count:$'  ;此句及以下4句为输出提示
    down_letter_count db 0dh,0ah,'downletter count:$' 
    digit_count db 0dh,0ah,'digit count:$'
    other_count db 0dh,0ah,'other count:$'
    CRLF db,0dh,0ah,'$'
DATAS ENDS

STACKS SEGMENT
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
MAIN PROC FAR
START:
    MOV AX,DATAS
    MOV DS,AX
    
    LEA DX,INPUT   ;在屏幕上显示输入提示
    MOV AH,9
    INT 21H
    
    LEA DX,STRING  ;输入字符串
    MOV AH,0AH
    INT 21H
    
    MOV CL,STRING[1]  ;设置循环次数,注意将CH置为0
    SUB CH,CH        
    LEA DI,STRING[2]  ;将指针指到缓冲区第一个字符,注意这里的2

CHECK:
	MOV AL,[DI]
	CMP AL,'$'     ;判断是否遍历结束,若是,则跳转输出
	JE EXIT
	CMP AL,30H    ;判断是否为数字
	JB O
	CMP AL,39H
	JNA D   
	CMP AL,41H    ;判断是否为大写字母
	JB O
	CMP AL,5AH
	JNA UP
	CMP AL,61H   ;判断是否为小写字母
	JB O
	CMP AL,7AH
	JNA DOWN    
	INC OTHER   ;若上面判断都不符合,则为其他字符。
	INC DI
	LOOP CHECK
	
O:	INC OTHER
	INC DI
	LOOP CHECK
D:	INC DIGIT
	INC DI
	LOOP CHECK
UP:	INC UP_LETTER
	INC DI
	LOOP CHECK
DOWN:INC DOWN_LETTER
	INC DI
	LOOP CHECK
	 
EXIT:  
	LEA DX,UP_LETTER_COUNT   ;输出大写字母计数提示
	MOV AH,09H
	INT 21H
	XOR AX,AX                ;将AX清空
	MOV AL,UP_LETTER        
	CALL DISPLAY             ;调用子程序,输出大写字母个数
	
	LEA DX,DOWN_LETTER_COUNT
	MOV AH,09H
	INT 21H
	XOR AX,AX
	MOV AL,DOWN_LETTER
	CALL DISPLAY           ;输出小写字母个数

	LEA DX,DIGIT_COUNT
	MOV AH,09H
	INT 21H
	XOR AX,AX
	MOV AL,DIGIT
	CALL DISPLAY         ;输出数字个数
	
	LEA DX,OTHER_COUNT
	MOV AH,09H
	INT 21H
	XOR AX,AX
	MOV AL,OTHER
	CALL DISPLAY  		;输出其他字符个数
	
	LEA DX,CRLF         ;回车,换行
	MOV AH,09H
	INT 21H
    MOV AH,4CH
    INT 21H
MAIN ENDP

DISPLAY PROC NEAR:
	MOV BL,10
	div BL
	PUSH AX;保留现场
	MOV DL,Al
	ADD DL,30H
	MOV AH,2
	INT 21H
	POP AX;恢复现场
	MOV DL,AH
	ADD DL,30H
	MOV AH,2
	INT 21H
	RET
DISPLAY ENDP

CODES ENDS
    END START

此段代码比较长,有几个点需要注意:

1、子程序DISPLAY中用到了PUSH和POP指令,这里的主要作用是保护现场,即保护AX中的内容。如果不进行此操作,下一步MOV AH,2时,AH的值就被修改,从而无法正确的输出统计的数字。

2、将统计的数字输出,先除以10,得到商和余数,此处先输出AL中的内容(商),再输出AH中的内容(余数)。

3、注意遍历字符串时,从STRING[2]开始。

输出结果:

image-20201116171724544

四、友情资源放送

此部分资源主要包括:

  1. 《汇编语言》第三版,王爽著,pdf版本
  2. 《清华大学IBM-PC汇编语言程序设计》第二版课后习题解答,沈美明著,pdf版本
  3. SHU汇编语言复习提纲

image-20201116173838285

image-20201116173913467

image-20201116172428454

王爽老师的汇编语言书确实通俗易懂,初学者友好。

这些资源都放在了我的GITHUB中,需要的朋友可以自取。

GITHUB地址:FM-Airknight的学习资源

祝所有读到这篇文章的朋友们都能有所收获!

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值