汇编语言基础
程序员文章站
2024-02-02 15:45:58
...
TITLE 8086 Code Template (for EXE file)
; AUTHOR [email protected]
; DATE 2008.9.1
; VERSION 1.00
; 5.3.2 循环程序的设计方法---1.计数控制循环(2)先判断
;
; 1.计数控制循环(循环次数已知) --(1)后判断;(2)先判断 ---C中 for() ---循环次数已知
;
; 2.条件控制循环(结束条件已知,数值条件)--(1)后判断;(2)先判断 ---C中 do{}while(); while(){ } --退出循环条件已经
;
; 3.变量控制循环(结束条件已知,地址条件)--(1)后判断;(2)先判断 ---while(1){ break;}
;
;
; 例5.3.2 page186---计数控制循环(2)先判断[1~10累加]
; 文件名: p186.ASM
;
; 整理:黄永平
; QQ:790516
; 主页:http://hi.baidu.com/hyper99/home
;-------------------------------------------------
; Directive to make EXE output:
#MAKE_EXE#
DSEG SEGMENT 'DATA'
NUMBER1 DB 1,2,3,4,5,6,7,8,9,10 ;数据
N EQU $-NUMBER1 ;个数
SUM1 DW ? ;保存结果
DSEG ENDS
SSEG SEGMENT STACK 'STACK'
DW 100h DUP(?)
SSEG ENDS
CSEG SEGMENT 'CODE'
;*******************************************
START PROC FAR ; 与RET对应
; Store return address to OS: 保存返回地址
PUSH DS
MOV AX, 0
PUSH AX
; set segment registers: 设置当前数据段DSEG
MOV AX, DSEG
MOV DS, AX
;---处理程序------
LEA BX, NUMBER1-1 ;初值指针-1
MOV AX, 0
MOV DH, 0
MOV CL, N+1 ; 初值计数值+1
next: INC BX ;指针+1
SUB CL,1 ;计数值-1
JZ exit ;计数值减到0时退出循环
MOV DL, [BX] ;取一个被加数
ADD AX, DX ;加到AX中
JMP next
exit: MOV SUM1, AX ;保存结果
;MOV AH,4CH
;INT 21H ;退出
; return to operating system: 返回操作系统
RET ; 执行int 20H中止
START ENDP
;*******************************************
CSEG ENDS
END START ; set entry point.
; 例5.3.2 page188---条件控制循环(2)先判断[1~10累加]
; 文件名: p188.ASM
;-------------------------------------------------
; Directive to make EXE output:
#MAKE_EXE#
DSEG SEGMENT 'DATA'
NUMBER1 DB 1,2,3,4,5,6,7,8,9,10 ;数据,以最后的数据值10做为结束条件
;N DB $-NUMBER1 ;个数
SUM1 DW ? ;保存结果
DSEG ENDS
SSEG SEGMENT STACK 'STACK'
DW 100h DUP(?)
SSEG ENDS
CSEG SEGMENT 'CODE'
;*******************************************
START PROC FAR ; 与RET对应
; Store return address to OS: 保存返回地址
PUSH DS
MOV AX, 0
PUSH AX
; set segment registers: 设置当前数据段DSEG
MOV AX, DSEG
MOV DS, AX
;---处理程序------
LEA BX, NUMBER1-1 ;
MOV AX, 10 ; 初值为10,最后一个数值
MOV DH, 0
next: INC BX
MOV DL, [BX] ;取一个被加数
CMP DL,10 ;取的数值与中止条件的数值进行比较
JZ exit ;最后取的数是10时,中止循环---结束条件
ADD AX, DX ;不是中止条件的数值,加到AX中
JMP next
exit: MOV SUM1, AX;保存结果
;MOV AH,4CH
;INT 21H ;退出
; return to operating system: 返回操作系统
RET ; 执行int 20H中止
START ENDP
;*******************************************
CSEG ENDS
END START ; set entry point.
; 例5.3.2 page189[1]---变量控制循环(1)后判断[1~10累加]
; 数据首地址为NUMBER1,N个字节数据尾地址为NUMBER1+N-1,取地址1000H+N为循环结束条件.
; 文件名: p189[1].ASM
;
; 整理:黄永平
; QQ:790516
; 主页:http://hi.baidu.com/hyper99/home
;-------------------------------------------------
; Directive to make EXE output:
#MAKE_EXE#
DSEG SEGMENT 'DATA'
NUMBER1 DB 1,2,3,4,5,6,7,8,9,10 ;十个数
SUM1 DW ? ;保存结果
DSEG ENDS
SSEG SEGMENT STACK 'STACK'
DW 100h DUP(?)
SSEG ENDS
CSEG SEGMENT 'CODE'
;*******************************************
START PROC FAR ; 与RET对应
; Store return address to OS: 保存返回地址
PUSH DS
MOV AX, 0
PUSH AX
; set segment registers: 设置当前数据段DSEG
MOV AX, DSEG
MOV DS, AX
;---处理程序------
LEA BX, NUMBER1 ;
MOV AX, 0 ; 累加器
MOV DH, 0
MOV CX,offset NUMBER1 +10 ;最后一个数的偏移地址加1,中止条件地址。
next: MOV DL, [BX] ;取一个被加数
ADD AX,DX ;累加到AX中
INC BX ;修改指针
CMP BX,CX ;BX与最后一个字节的地址+1比较
JNZ next ; 没达到中止条件的地址,继续循环。
MOV SUM1, AX;保存结果
;MOV AH,4CH
;INT 21H ;退出
; return to operating system: 返回操作系统
RET ; 执行int 20H中止
START ENDP
;*******************************************
CSEG ENDS
END START ; set entry point.
; 例5.3.2 page190---求无符号整数平方根整数部分
;利用n^2=1+3+5...+(2n-1),从给定值中依次减去1,3,5...,2n-1,
;减到有借位为止,减法的次数就是要求的结果。
; 文件名: p190[1].ASM
;
; 整理:黄永平
; QQ:790516
; 主页:http://hi.baidu.com/hyper99/home
;-------------------------------------------------
; Directive to make EXE output:
#MAKE_EXE#
DSEG SEGMENT 'DATA'
NUMBER1 DW 25
ROOT1 DW ?
DSEG ENDS
SSEG SEGMENT STACK 'STACK'
DW 100h DUP(?)
SSEG ENDS
CSEG SEGMENT 'CODE'
;*******************************************
START PROC FAR ; 与RET对应
; Store return address to OS: 保存返回地址
PUSH DS
MOV AX, 0
PUSH AX
; set segment registers: 设置当前数据段DSEG
MOV AX, DSEG
MOV DS, AX
;---处理程序------
;----实现1,书中实现---------------------
MOV AX, NUMBER1 ;取值
MOV CX, -1 ;计数次数-1
MOV BX, -1 ;被减数-2
next1: ADD BX, 2 ;奇数1,3,5...
SUB AX, BX ;减1,3,5...
INC CX ;计数+1 ,不影响CF,最后多加一次
JNC next1 ;够减循环
MOV ROOT1, CX ;保存结果
;MOV AH,4CH
;INT 21H ;退出
; return to operating system: 返回操作系统
RET ; 执行int 20H中止
START ENDP
;*******************************************
CSEG ENDS
END START ; set entry point.
; 例5.3.2 page191---CRT上显示“中”字
; 文件名: p191.ASM
;
; 整理:黄永平
; QQ:790516
; 主页:http://hi.baidu.com/hyper99/home
;-------------------------------------------------
; Directive to make EXE output:
#MAKE_EXE#
DSEG SEGMENT 'DATA'
NUMBER1 DB 0Ah,0Dh
DB ' A ',0Ah,0Dh
DB 'AAAAAAA',0Ah,0Dh
DB 'A A A',0Ah,0Dh
DB 'A A A',0Ah,0Dh
DB 'AAAAAAA',0Ah,0Dh
DB ' A ',0Ah,0Dh
DB ' A ',0Ah,0Dh
N DB $-NUMBER1
DSEG ENDS
SSEG SEGMENT STACK 'STACK'
DW 100h DUP(?)
SSEG ENDS
CSEG SEGMENT 'CODE'
;*******************************************
START PROC FAR ; 与RET对应
; Store return address to OS: 保存返回地址
PUSH DS
MOV AX, 0
PUSH AX
; set segment registers: 设置当前数据段DSEG
MOV AX, DSEG
MOV DS, AX
;---处理程序------
LEA BX, NUMBER1
MOV CH, 0
MOV CL, N ;7行*9个字符/行+2个字符 =65
next: MOV DL, [BX]
MOV AH, 2 ;显示DL中的ASCII码
INT 21H
INC BX
LOOP next
;MOV AH,4CH
;INT 21H ;退出
; return to operating system: 返回操作系统
RET ; 执行int 20H中止
START ENDP
;*******************************************
CSEG ENDS
END START ; set entry point.
; 5.2.3 多路分支程序设计方法---(3)段内转移表法
;
; a.段内短转移:(jmp disp8为2字节指令)
; 转移表地址=转移表首地址+(键号-1)*2
; b.段内近转移:(jmp disp16为3字节指令)
; 转移表地址=转移表首地址+(键号-1)*3
; c.段间远转移:(jmp disp32为4字节指令)
; 转移表地址=转移表首地址+(键号-1)*4
;
; 例5.2.2 page183
; 文件名: p183.ASM
;
; 整理:黄永平
; QQ:790516
; 主页:http://hi.baidu.com/hyper99/home
;-------------------------------------------------
; Directive to make EXE output:
#MAKE_EXE#
DSEG SEGMENT 'DATA'
DSEG ENDS
SSEG SEGMENT STACK 'STACK'
DW 100h DUP(?)
SSEG ENDS
CSEG SEGMENT 'CODE'
;*******************************************
START PROC FAR ; 与RET对应
; Store return address to OS: 保存返回地址
PUSH DS
MOV AX, 0
PUSH AX
; set segment registers: 设置当前数据段DSEG
MOV AX, DSEG
MOV DS, AX
;---处理程序------
LEA BX, [WORK]
MOV AH,1
INT 21H ;输入键号
AND AL,0FH
DEC AL ;键号-1
MOV AH,AL
ADD AL,AL
ADD AL,AH ;(键号-1)*3
SUB AH,AH
ADD BX,AX ;转移表首地址+(键号-1)*3
JMP BX
;---跳转表
WORK:
JMP NEAR PTR WORK1 ;3字节,进行了优化,变成了2个字节
JMP NEAR PTR WORK2
JMP NEAR PTR WORK3
JMP NEAR PTR WORK4
JMP NEAR PTR WORK5
;---工作模块
WORK1:
MOV AH,0EH ;sub-function
MOV AL,'A' ;要显示的字符
INT 10h
jmp work0
WORK2:
MOV AH,0EH ;sub-function
MOV AL,'B' ;要显示的字符
INT 10h
jmp work0
WORK3:
MOV AH,0EH ;sub-function
MOV AL,'C' ;要显示的字符
INT 10h
jmp work0
WORK4:
MOV AH,0EH ;sub-function
MOV AL,'D' ;要显示的字符
INT 10h
jmp work0
WORK5:
MOV AH,0EH ;sub-function
MOV AL,'E' ;要显示的字符
INT 10h
jmp work0
WORK0:
MOV AH,4CH
INT 21H
; return to operating system: 返回操作系统
RET ; 执行int 20H中止
START ENDP
;*******************************************
CSEG ENDS
END START ; set entry point.
; 5.2.3 多路分支程序设计方法---(1)逻辑分解法
; 一个一个判断
; 例5.2.2 page181
; 文件名: p181.ASM
; 整理:黄永?
; QQ:790516
; 主页:http://hi.baidu.com/hyper99/home
;-------------------------------------------------
; Directive to make EXE output:
#MAKE_EXE#
DSEG SEGMENT 'DATA'
DSEG ENDS
SSEG SEGMENT STACK 'STACK'
DW 100h DUP(?)
SSEG ENDS
CSEG SEGMENT 'CODE'
;*******************************************
START PROC FAR ; 与RET对应
; Store return address to OS: 保存返回地址
PUSH DS
MOV AX, 0
PUSH AX
; set segment registers: 设置当前数据段DSEG
MOV AX, DSEG
MOV DS, AX
;---选择程序------
MOV AH,1
INT 21H ;键入值
CMP AL,31H
JZ WORK1
CMP AL,32H
JZ WORK2
CMP AL,33H
JZ WORK3
CMP AL,34H
JZ WORK4
CMP AL,35H
JZ WORK5
JMP WORK0
;---工作模块
WORK1:
MOV AH,0EH ;sub-function
MOV AL,'A' ;要显示的字符
INT 10h
jmp work0
WORK2:
MOV AH,0EH ;sub-function
MOV AL,'B' ;要显示的字符
INT 10h
jmp work0
WORK3:
MOV AH,0EH ;sub-function
MOV AL,'C' ;要显示的字符
INT 10h
jmp work0
WORK4:
MOV AH,0EH ;sub-function
MOV AL,'D' ;要显示的字符
INT 10h
jmp work0
WORK5:
MOV AH,0EH ;sub-function
MOV AL,'E' ;要显示的字符
INT 10h
jmp work0
WORK0:
MOV AH,4CH
INT 21H
; return to operating system: 返回操作系统
RET ; 执行int 20H中止
START ENDP
;*******************************************
CSEG ENDS
END START ; set entry point.
; 5.2.3 多路分支程序设计方法---(2)地址表法;
; 转移表地址=转移表首地址+(键号-1)*2
; 例5.2.2 page182
; 文件名: p182.ASM
;
; 整理:黄永平
; QQ:790516
; 主页:http://hi.baidu.com/hyper99/home
;-------------------------------------------------
; Directive to make EXE output:
#MAKE_EXE#
DSEG SEGMENT 'DATA'
TABLE DW WORK1,WORK2,WORK3,WORK4,WORK5 ;跳转地址表
DSEG ENDS
SSEG SEGMENT STACK 'STACK'
DW 100h DUP(?)
SSEG ENDS
CSEG SEGMENT 'CODE'
;*******************************************
START PROC FAR ; 与RET对应
; Store return address to OS: 保存返回地址
PUSH DS
MOV AX, 0
PUSH AX
; set segment registers: 设置当前数据段DSEG
MOV AX, DSEG
MOV DS, AX
;---------
LEA BX,TABLE ;表首地址
MOV AH,1
INT 21H
AND AL,0FH
DEC AL ;键号-1
ADD AL,AL ;(键号-1)*2
SUB AH,AH
ADD BX,AX ;表地址 = 表首地址 + (键号-1)*2
JMP WORD PTR[BX] ;跳转到work1~work5
;---工作模块
WORK1:
MOV AH,0EH ;sub-function
MOV AL,'A' ;要显示的字符
INT 10h
jmp work0
WORK2:
MOV AH,0EH ;sub-function
MOV AL,'B' ;要显示的字符
INT 10h
jmp work0
WORK3:
MOV AH,0EH ;sub-function
MOV AL,'C' ;要显示的字符
INT 10h
jmp work0
WORK4:
MOV AH,0EH ;sub-function
MOV AL,'D' ;要显示的字符
INT 10h
jmp work0
WORK5:
MOV AH,0EH ;sub-function
MOV AL,'E' ;要显示的字符
INT 10h
jmp work0
WORK0:
MOV AH,4CH
INT 21H
; return to operating system: 返回操作系统
RET ; 执行int 20H中止
START ENDP
;*******************************************
CSEG ENDS
END START ; set entry point.
; 5.2.2 二路分支程序设计方法
; 例5.2.1 page180
; 文件名: p180.ASM
; 整理:黄永?
; QQ:790516
; 主页:http://hi.baidu.com/hyper99/home
;-------------------------------------------------
; Directive to make EXE output:
#MAKE_EXE#
DSEG SEGMENT 'DATA'
XX1 DB 10 ; X=给定一个值
YY1 DB ? ; Y结果
DSEG ENDS
SSEG SEGMENT STACK 'STACK'
DW 100h DUP(?)
SSEG ENDS
CSEG SEGMENT 'CODE'
;*******************************************
START PROC FAR ; 与RET对应
; Store return address to OS: 保存返回地址
PUSH DS
MOV AX, 0
PUSH AX
; set segment registers: 设置当前数据段DSEG
MOV AX, DSEG
MOV DS, AX
;
MOV AL,XX1
CMP AL, 0
JZ AA1 ;=0
JNS AA2
MOV AL,0FFH ;=-1
JMP AA1
AA2: MOV AL,1 ;=1
AA1:MOV YY1,AL;
;MOV AH,4CH ;中止程序
;INT 21H
; return to operating system: 返回操作系统
RET ; 执行int 20H中止
START ENDP
;*******************************************
CSEG ENDS
END START ; set entry point.
下一篇: 汇编语言实验——求绝对值之和