欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

汇编语言基础

程序员文章站 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.