8086汇编总结整理

架构简介

8086是16位寄存器和16位外部数据总线,20位地址总线,寻址为1MB的地址空间。

架构为基于累加器的寄存器-内存架构,可以对内存数直接操作,不同于MIPS的寄存器-寄存器架构运算数和结果都在寄存器中。这意味着,和MIPS相比,一方面寄存器-内存的架构使得8086中有许多可以直接操作内存的指令,避免了进行取-计算-存这样的步骤;另一方面,基于累加器的特点使得8086指令集中INC和DEC的方便高效尤为突出,运算指令集也很自然地呈现了不一样的结构。

寄存器简介

通用寄存器

8个通用寄存器
     
AX

乘除法的第一个操作数;乘除法返回的部分(16位,8位全部)结果;

串操作中load和store操作的寄存器(AX,AL);

系统调用功能号(AH);

可作为通用寄存器或寄存器传参进行函数调用时返回值存放处

 
BX

间接寻址的基址寄存器;

通用寄存器

 
CX   

LOOP计数器;

移位寄存器(移位次数)

 
DX

16位乘法中乘积高16位,32位/16位被除数高位及余数;

部分系统调用内容 DL

 
SP 堆栈指针  
BP

相对堆栈段的相对寻址的基址寄存器,相对SS段寻址;

堆栈传参的基址寄存器

 
SI

串操作的源变址寄存器;

基址加变址相对寻址的变址寄存器

相对于DS寻址

 
DI

串操基址加变址相对寻址的变址寄存器作的目的变址寄存器;

基址加变址相对寻址的变址寄存器

相对于DS或ES(串操作)寻址

 

段寄存器

段寄存器包括CS(代码段)、DS(数据段)、SS(堆栈段)、ES(附加段)

指令指针

IP,当前代码在CS中的偏移。类似MIPS的PC。

标志寄存器

8086有9个一位标志寄存器(标志位),放在16位的寄存器PSW(program status word)中。

其中特别注意,ZF表示结果是否为0,结果为0则ZF=1; SF表示结果是否为负,结果小于0则SF=1。


内存组织

段式内存管理,相比之前OS中做的分页式内存管理更加灵活。

内存中(非堆栈段)存储内存由低到高增长,存储遵循低字在前、高字在后,低字节在前、高字节在后。

堆栈也遵循低字节在前、高字节在后,

堆栈操作
PUSH 

(1) SP -= 2

(2)  ->[SP] 

POP

(1) [SP] ->

(2) SP += 2 


地址表示与寻址:

段地址: 偏移

地址 = 段地址 << 4 + 偏移


指令系统

基本形式:

op dst src

第一个小程序:反向冒泡排序

STACK1		SEGMENT	PARA STACK				;?
STACK_AREA	DW	100H DUP(?)				
STACK_BTM	EQU	$ - STACK_AREA				
STACK1		ENDS

DATA1		SEGMENT
TABLE_LEN	DW	20
TABLE		DW	200,300,400,10,20,0,1,8
		DW	41H,40,42H,50,60,0FFFFH,2,3
                DW      15H,0613H,1506H,1061H
DATA1 		ENDS

CODE1		SEGMENT
		ASSUME	CS:CODE1,DS:DATA1,SS:STACK1		;ASSUME CS:CODE1	\n	ASSUME DS:DATA1
MAIN		PROC 	FAR					;main{
		MOV 	AX,STACK1
        	MOV 	SS,AX                  
        	MOV 	SP,STACK_BTM         
        	MOV 	AX,DATA1                 
        	MOV 	DS,AX					;init SS,SP,DS
        	
LP1:            MOV	BX,1
		MOV	CX,TABLE_LEN
		DEC	CX					;--
		MOV	SI,OFFSET TABLE
LP2:		MOV	AX,[SI]
		CMP	AX,[SI+2]
		JAE	CONTINUE
		XCHG	AX,[SI+2]
		MOV	[SI],AX
		MOV	BX,0
CONTINUE:	ADD	SI,2
		LOOP	LP2
		CMP	BX,1
		JZ	PRINTRES
		JMP	SHORT LP1

; print hex results 
PRINTRES:   MOV	CX,20							
        MOV	SI,OFFSET TABLE

LP4:    PUSH CX
        MOV CX,4;pro counter for loop of rol
           	
        MOV BX,[SI]
LP3:    PUSH CX
        MOV CL,4
        ROL BX,CL
        MOV AL,BL
        AND AL,0FH
        ADD AL,30H
        CMP AL,39H
        JBE DISP
        ADD AL,'A'-'9'-1

DISP:   MOV DL,AL
        MOV AH,2
        INT 21H
        POP CX
        LOOP LP3

        MOV DL,' '
        MOV AH,2
        INT 21H

        POP CX
        ADD SI,2
        LOOP LP4
  
		
EXIT:		MOV	AX,4C00H
		INT	21H					;return 0
MAIN		ENDP						;}
CODE1 		ENDS
		END 	MAIN					;total end	begin: main function

示例程序中将数组冒泡排序并按十六进制输出,使用了多重LOOP循环、相对寻址、跳转、系统调用。


输入输出

第一次作业中写了将数组十进制、十六进制输出的代码,上面已经展示过16进制输出了,下面是十进制输出的代码片段。

; print  results at base 10
PRINTRES:MOV CX,20							
        MOV SI,OFFSET TABLE

LP3:    PUSH CX
        MOV CX,5
        MOV AX,[SI]
        MOV BX,10

LP4:    XOR DX,DX
        DIV BX
        OR DL,30H
        PUSH DX
        LOOP LP4

        MOV CX,5
LP5:    POP DX
        MOV AH,2
        INT 21H
        LOOP LP5

        MOV DL,' '
        MOV AH,2
        INT 21H
        POP CX
        ADD SI,2
        LOOP LP3
  

数字操作

第三次作业总结了几个关于数字进制转换的函数,包括输入输出。

CHANGEBASEIN  PROC
;PARAM: input_string offset, base
;       
    PUSH BP
    MOV BP,SP
    
    ;get params reversely
    PUSH SI
    PUSH AX
    PUSH BX
    PUSH CX
    PUSH DX
    MOV SI,[BP+6] 
    MOV BX,[BP+4]
    
    PUSH 0
READ_DIGIT:
    XOR AX,AX
    LODSB 
    CMP AL,'$'
    JZ READ_OK
    CMP AL,'A'
    JB DGT2NUM
    ADD AX,-'A'+0AH+'0'
DGT2NUM:SUB AX,30H
    MOV CX,AX
    POP AX
    MUL BX
    ADD AX,CX
    PUSH AX
    JMP READ_DIGIT
    
READ_OK:POP AX
    MOV [BP+6],AX    

    POP DX
    POP CX
    POP BX
    POP AX
    POP SI
    POP BP
    
    RET 2

CHANGEBASEIN  ENDP

CHANGEBASEOUT  PROC
;PARAM: number, base
;       
    PUSH BP
    MOV BP,SP
    
    ;get params reversely
    PUSH AX
    PUSH BX
    PUSH CX
    PUSH DX
    MOV AX,[BP+6] 
    MOV BX,[BP+4]
    
    XOR CX,CX
GET_DIGIT:
    XOR DX,DX
    DIV BX
    CMP DX,0AH
    JB DIGIT2CHAR
    ADD DX,'A'-0AH-'0'
DIGIT2CHAR:ADD DX,30H
    PUSH DX
    INC CX
    CMP AX,0
    JNZ GET_DIGIT

POP_DIGITS:
    POP DX
    MOV AH,2
    INT 21H
    LOOP POP_DIGITS

    POP DX
    POP CX
    POP BX
    POP AX
    POP BP
    
    RET 4

CHANGEBASEOUT  ENDP

CHANGEBASEIN将一个指定基的字符串转换为一个数,CHANGEBASEOUT将一个内存数以指定的进制输出。将这两个函数组合可以实现任意进制转换。

串操作

串操作的指令默认源是DS:SI,目的是ES:DI,默认load store寄存器是AX/AL。

插入

INSERT  PROC
;PARAMS:OFFSET STR, char, pos

    PUSH BP
    MOV BP,SP

    PUSH SI
    PUSH AX
    PUSH CX

    MOV SI,[BP+8]

    ADD SI,[BP+4]
    XOR CX,CX
    CLD
LP00:INC CX
    LODSB
    CMP AL,'$'
    JNZ LP00
    MOV DI,SI
    DEC SI
    STD
    REP MOVSB
    INC SI
    MOV AX,[BP+6]
    STOSB

    POP CX
    POP AX
    POP SI
    POP BP
    RET 6

INSERT  ENDP

删除

DELETE  PROC
;PARAMS:OFFSET STR, pos

    PUSH BP
    MOV BP,SP

    PUSH SI
    PUSH DI
    PUSH AX

    MOV SI,[BP+6]

    ADD SI,[BP+4]
    MOV DI,SI
    INC SI
    
    CLD
LP9:MOV AL,[SI]
    MOVSB
    CMP AL,'$'
    JNZ LP9
    

    POP AX
    POP DI
    POP SI
    POP BP
    RET 4

DELETE  ENDP

修改

MODIFY  PROC
;PARAMS:OFFSET STR, char, pos

    PUSH BP
    MOV BP,SP

    PUSH DI
    PUSH AX

    MOV DI,[BP+8]

    ADD DI,[BP+4]
    MOV AX,[BP+6]
    STOSB

    POP AX
    POP DI
    POP BP
    RET 6

MODIFY  ENDP

查找

FIND    PROC
;PARAMS:OFFSET STR1, OFFSET STR2,LEN STR2

    PUSH BP
    MOV BP,SP

    PUSH SI
    PUSH DI
    PUSH CX

    MOV SI,[BP+8]

    MOV [BP+8],0 ;RETURN VALUE
    
    PUSH SI
LP10:POP SI 
    INC SI
    PUSH SI
    MOV DI,[BP+6]
    MOV CX,[BP+4]
    CLD
    REPE CMPSB
    CMP CX,0
    JZ EQUAL
    CMP [SI],'$'
    JZ NOTEQ
    JMP LP10

EQUAL:
    INC [BP+8]
NOTEQ:

    POP SI
    
    POP CX
    POP DI
    POP SI

    POP BP

    RET 4;One return value, 1 for issub, 0 for not
FIND    ENDP

字符串比较

STRCMP  PROC
;PARAMS STR1,STR2,LEN1,LEN2
;RETURN 1 FOR STR1>STR2; 0 FOR EQUAL; -1 FOR STR1STR2
    
SMALL:DEC [BP+10]
    
OK:    POP CX
    POP DI
    POP SI

    POP BP

    RET 6

STRCMP  ENDP

大小写转换

TOUPPER PROC
;PARAMS:OFFSET STR
    PUSH BP
    MOV BP,SP

    PUSH SI
    PUSH AX

    MOV  SI,[BP+4]
    XOR AX,AX
    CLD
LOW2UP:LODSB
    CMP AL,'$'
    JZ L2UOK
    CMP AL,'Z'
    JBE LOW2UP  
    SUB  [SI-1],20H
    JMP LOW2UP

L2UOK:
    POP AX
    POP SI

    POP BP

    RET 2

TOUPPER ENDP


TOLOWER   PROC
;PARAMS:OFFSET STR
    PUSH BP
    MOV BP,SP

    PUSH SI
    PUSH AX
    XOR AX,AX
    CLD
    MOV  SI,[BP+4]
UP2LOW:LODSB
    CMP AL,'$'
    JZ U2LOK
    CMP AL,'a'
    JAE UP2LOW  
    ADD  [SI-1],20H
    JMP UP2LOW

U2LOK:
    POP AX
    POP SI

    POP BP

    RET 2

TOLOWER ENDP

复制

COPY    PROC
;PARAMS: SRC, DET
    PUSH BP
    MOV BP,SP

    PUSH SI
    PUSH DI
    PUSH AX
    
    MOV SI,[BP+6]
    MOV DI,[BP+4]
    
CP: LODSB
    DEC SI
    MOVSB
    CMP AL,'$'
    JNZ CP
    
    POP AX
    POP DI
    POP SI

    POP BP
    RET 4

COPY    ENDP

输出字符串数组

OUTPUT_STR_ARRAY    PROC
;DI ARRAY_HEAD
;DX ALL_STR_LEN
            PUSH    BP
            MOV     BP,SP

            PUSH    AX
            PUSH    DI
            PUSH    SI
            PUSH    DX  

            MOV     DI,[BP+6]
            MOV     DX,[BP+4]

            PUSH    DX
            MOV     CX,DX
            MOV     AH,2
LP_HEAD:    MOV     DL,[DI]
            INC     DI
            CMP     DL,'$'
            JNZ     NOTEND
            MOV     DL,0AH      
            INT     21H
            MOV     DL,0DH
NOTEND:     INT     21H
            LOOP    LP_HEAD

            POP     DX

            POP     DX
            POP     SI
            POP     DI
            POP     AX

            POP     BP
            ;RET
            RET 4

OUTPUT_STR_ARRAY    ENDP

; print  results at base 10
PRINTRES PROC     
;PARAMS:
;DX BUFF LEN
;SI HEAD OFFSET 
        PUSH BP
        MOV BP,SP
        PUSH CX
        PUSH DX
        PUSH BX
        PUSH SI

        
        MOV CX,[BP+6];MOV	CX,DX
        MOV SI,[BP+4]							

LP3:    PUSH CX
        MOV CX,5
        MOV	AX,[SI]
        MOV BX,10

LP4:    XOR DX,DX
        DIV BX
        OR DL,30H
        PUSH DX
        LOOP LP4

        MOV CX,5
LP5:    POP DX
        MOV AH,2
        INT 21H
        LOOP LP5

        MOV DL,' '
        MOV AH,2
        INT 21H
        POP CX
        ADD SI,2
        LOOP LP3

        POP SI
        POP BX
        POP DX
        POP CX

        POP BP

        RET 4
                
PRINTRES    ENDP

字符串数组字典序排序

DICT_SORT   PROC
;PARAMS: offset of head of array,  buffer len, array len
            PUSH BP
            MOV BP,SP

            PUSH AX
            PUSH BX
            PUSH CX
            PUSH DX
            PUSH SI
            PUSH DI

            MOV     DI,[BP+8] ;OFFSET BUFF
            MOV     DX,[BP+6] ;BUFF_LEN
            PUSH    DI
            PUSH    DX
            CALL    OUTPUT_STR_ARRAY

;get str head pointer 
            MOV     DI,[BP+8]
            MOV     CX,4
            MOV     SI,OFFSET ADDR_STR
            MOV     BX,OFFSET STR_LEN
            MOV     [SI],DI
           
LP_HEAD2:   MOV     DL,[DI]
            INC     DI
            CMP     DL,'$'
            JNZ     LP_HEAD2
            MOV     AX,DI
            SUB     AX,[SI]
            MOV     [BX],AX
            ADD     BX,2
            CMP     CX,1
            JBE     LASTSTR

            ADD     SI,2
            MOV     [SI],DI
            
LASTSTR:    LOOP    LP_HEAD2
            
            
;MOV     AH,2
;MOV     DL,'a'
;INT 21H

;initiate index
        MOV CX,[BP+4]
        MOV AX,0
        MOV SI,OFFSET INDEX
INDEX_INIT:MOV [SI],AX
        ADD SI,2
        INC AX
        LOOP INDEX_INIT


LP1:    MOV	DX,1
		MOV	CX,4
		DEC	CX					;--
    	MOV     BX,OFFSET INDEX
LP2:    PUSH    CX   
        MOV     SI,[BX] ; index of current string
        MOV     DI,[BX+2] ;
        SAL     SI,1
        SAL     DI,1

        MOV     CX,[SI+OFFSET STR_LEN]     
   
        MOV	    SI,[SI+OFFSET ADDR_STR]
        MOV     DI,[DI+OFFSET ADDR_STR]        
        ;CMP  
        CLD
		REPE    CMPSB

;MOV     AH,0
;INT 16H
        
        POP     CX
        JBE     CONTINUE;STR1 <= STR2   
        
        MOV     AX,[BX]   
		XCHG	AX,[BX+2]
		MOV	    [BX],AX
		MOV	    DX,0
CONTINUE:ADD	BX,2
		LOOP	LP2
		CMP	DX,1
        JZ  END        
		JMP	SHORT LP1  
            
END:     
        PUSH [BP+4]
        PUSH OFFSET INDEX
        CALL    PRINTRES
   
       MOV     CX,[BP+4]
        MOV     DI,OFFSET TMP_BUFF
        MOV     BX,OFFSET INDEX
LP6:        MOV     SI,[BX]
        PUSH    CX
        SAL     SI,1
        MOV     CX,[SI+OFFSET STR_LEN]
        MOV     SI,[SI+OFFSET ADDR_STR]
        CLD
        REP     MOVSB
        POP     CX
        ADD     BX,2
        LOOP    LP6

        MOV CX,[BP+6]
        MOV SI,OFFSET TMP_BUFF
        MOV DI,[BP+8]
        REP MOVSB
        PUSH [BP+8]
        PUSH [BP+6]
        CALL OUTPUT_STR_ARRAY 


        POP DI
        POP SI
        POP DX
        POP CX
        POP BX
        POP AX

        POP BP

        RET 6

DICT_SORT   ENDP

子程序与堆栈传参

procname PROC

...
RET
procname ENDP

如上形式可以定义一个函数(过程),可以使用寄存器传参数(如DX,DI)与返回值(如AX),也可使用堆栈传参。

第二次作业中多使用寄存器传参,第三次第四次中使用堆栈传参。

堆栈传参使用BP作为子程序寻址基址,注意PUSH BP之后立刻MOV BP,SP,不然会发生寻址错误。另外由于堆栈FILO的性质,参数压栈和取参数的顺序相反。

子程序看到的堆栈情况简化:


... 父程序保存的堆栈内容
BP+4 最后一个参数
BP+2 IP
BP 子程序PUSH的原BP
... 子程序保存的堆栈内容

堆栈传参尤其注意保护现场与堆栈平衡。

下面是两个递归调用的例子,分别是计算阶乘和计算斐波那契数。

STACK1		SEGMENT	PARA STACK				;?
STACK_AREA	DW	100H DUP(?)				
STACK_BTM	EQU	$ - STACK_AREA				
STACK1		ENDS

DATA1		SEGMENT
X	        DW	 4
DATA1 		ENDS

CODE1		SEGMENT
		ASSUME	CS:CODE1,DS:DATA1,SS:STACK1		;ASSUME CS:CODE1	\n	ASSUME DS:DATA1
MAIN		PROC 	FAR					;main{
		    MOV 	AX,STACK1
        	MOV 	SS,AX                  
        	MOV 	SP,STACK_BTM         
        	MOV 	AX,DATA1                 
        	MOV 	DS,AX					;init SS,SP,DS

            PUSH    8
            CALL    FACT
            ;POP & PUSH
            PUSH 10
            CALL CHANGEBASEOUT          
		
EXIT:		MOV	AX,4C00H
		INT	21H					;return 0
MAIN		ENDP						;}


FACT PROC
;PARAM :N
;RETURN N!

    PUSH BP
    MOV BP,SP
    PUSH AX
    PUSH BX
    PUSH DX
    
    CMP [BP+4],1
    JBE END
    PUSH [BP+4]
    DEC [BP+4]
    PUSH [BP+4]
    CALL FACT
    POP AX ;(N-1)!
    POP BX ;N
    MUL BX
    MOV [BP+4],AX

END:
    POP DX
    POP BX
    POP AX
    POP BP

    RET

FACT  ENDP


CHANGEBASEOUT  PROC
;PARAM: number, base
;       
    PUSH BP
    MOV BP,SP
    
    ;get params reversely
    PUSH AX
    PUSH BX
    PUSH CX
    PUSH DX
    MOV AX,[BP+6] 
    MOV BX,[BP+4]
    
    XOR CX,CX
GET_DIGIT:
    XOR DX,DX
    DIV BX
    CMP DX,0AH
    JB DIGIT2CHAR
    ADD DX,'A'-0AH-'0'
DIGIT2CHAR:ADD DX,30H
    PUSH DX
    INC CX
    CMP AX,0
    JNZ GET_DIGIT

POP_DIGITS:
    POP DX
    MOV AH,2
    INT 21H
    LOOP POP_DIGITS

    POP DX
    POP CX
    POP BX
    POP AX
    POP BP
    
    RET 4

CHANGEBASEOUT  ENDP

CODE1 		ENDS
		END 	MAIN					;total end	begin: main function


后续持续更新中,欢迎交流指正。

你可能感兴趣的:(8086汇编总结整理)