汇编-例子解析(一)

4-例子解析

一、hello实例

DSEG SEGMENT

MESSAGE DB 'How do you do',0DH,0AH,24H

DSEG ENDS

CSEG SEGMENT

ASSUME CS:CSEG,DS:DSEG

BEGIN:

MOV AX,DSEG

MOV DS,AX

MOV DX,OFFSET MESSAGE

MOV AH,9

INT 21H

MOV AH,4CH

INT 21H

CSEG ENDS

END BEGIN

DOS功能调用步骤:

(1) 根据不同的功能调用,准备入口参数

(2) 把功能号送到AH寄存器中

(3) 发软中断指令“INT 21H”

9号功能说明

汇编-例子解析(一)

4CH号功能说明

退出程序

代码说明:

(1)0DH,0AH,24H代表’$’

(2)ASSUME声明段寄存器

(3)MOV AX,DSEG 和 MOV DS,AX,设置数据段寄存器内容。

DSEG和普通变量以及寄存器相同,代表一个地址。

(4)OFFSET MESSAGE,变量MESSAGE在数据段中的偏移量

(5)DS和DX都是为了9号功能做准备

二、16X+Y实例

DSEG SEGMENT

XXX DW 1234H

YYY DW 5678H

ZZZ DD ?

DSEG ENDS

CSEG SEGMENT

ASSUME CS:CSEG, DS:DSEG

START:MOV AX,DSEG

MOV DS,AX

MOV AX,XXX

XOR DX,DX

ADD AX,AX

ADC DX,DX

ADD AX,AX

ADC DX,DX

ADD AX,AX

ADC DX,DX

ADD AX,AX

ADC DX,DX

ADD AX,YYY

ADC DX,0

MOV WORD PTR ZZZ, AX

MOV WORD PTR ZZZ+2,DX

MOV AH,4CH

INT 21H

CSEG ENDS

END START

如何查看结果?

(1) DEBUG TEST.EXE

(2) R显示所有寄存器的值

(3) U显示代码指令

(4) T一步步执行

(5) D显示内存单元值,具体为D DS:0004,也就是ZZZ的开始地址

(6) 判断ZZZ是否是0179B8H = 1234H*10H+5678H=12340H+5678H

代码理解:

(1) XOR DX,DX,将DX清0,异或就是相同为0,不同为1

(2) ADC OPRD1,OPRD2 <=> OPRD1 = OPRD1 + OPRD2 + CF

ADC DX,DX的前一步是ADD AX,AX , 如果有进位的话,则保存在DX中,也就是DX保存结果的高16位,AX保存结果的低16位。

(3) ADC DX,DX和ADC DX,0区别。前者对应ADD AX,AX,既然低16位相加了,高16位也要相加;后者对应ADD AX,YYY,不涉及高16位相加,所以只加CF。

(4) ZZZ和ZZZ+2区别。虽然ZZZ经过PTR强制转换成了WORD,但步进的单位始终是BYTE,则ZZZ+2代表的是高16位的开始地址。

改进例子:

DSEG SEGMENT

XXX DW 1234H

YYY DW 5678H

ZZZ DD ?

DSEG ENDS

CSEG SEGMENT

ASSUME CS:CSEG, DS:DSEG

START:MOV AX,DSEG

MOV DS,AX

MOV AX,XXX

XOR DX,DX

MOV DX,16

MUL DX

ADD AX,YYY

ADC DX,0

MOV WORD PTR ZZZ, AX

MOV WORD PTR ZZZ+2,DX

MOV AH,4CH

INT 21H

CSEG ENDS

END START

注意:MUL OPRD

如果OPRD是字节操作数,则把AL中的无符号数与OPRD相乘,16位结果送到AX中;

如果OPRD是双字节数,则把AX中的无符号数与OPRD相乘,32位结果送到DX和AX中,其中DX含有高16位,AX含有低16位。

因为DX是16位,则执行MUL DX的结果是:AX含有低16位,DX含有高16位.

三、BCDASCII

DSEG SEGMENT

BCD DB 86H

ASCII DB 2 DUP(0)

DSEG ENDS

CSEG SEGMENT

ASSUME CS:CSEG, DS:DSEG

START:

MOV AX,DSEG ;Set data segment

MOV DS,AX

MOV AL,BCD ;Convert low 4 bits to ascii and save it in ASCII[1]

MOV DL,0FH

AND AL,DL

ADD AL,30H

MOV ASCII+1,AL

MOV AL,BCD ;Convert high 4 bits to ascii and save it in ASCII[0]

MOV CL,4

SHR AL,CL

ADD AL,30H

MOV ASCII,AL

CSEG ENDS

END START

BCD码与ASCII码之间的转换:BCD+30H = ASCII

压缩BCD码,是指在一个byte中的低4bits存放一个BCD码,高4bits中存放一个BCD码。

最后通过DEBUG指令D DS:0001验证得到38 36

4、查表法

DSEG SEGMENT

VALUE DB 4

ANSWER DW ?

TAB DW 0,3010,4771,6021,6990,7782,8451,9031,9542,10000

DSEG ENDS

CSEG SEGMENT

ASSUME CS:CSEG,DS:DSEG

START:MOV AX,DSEG

MOV DS,AX

MOV AL,VALUE

XOR AH,AH

DEC AX

ADD AX,AX

MOV BX,AX

MOV AX,TAB[BX]

MOV ANSWER,AX

MOV AH,4CH

INT 21H

CSEG ENDS

END START

注意:

(1) MOV AL,VALUE。因为VALUE是单个BYTE

(2) XOR AH,AH。在使用AX之前,必须这样,否则为乱码

(3) DEC AX。减1,对应着数组下标

(4) ADD AX,AX。TAB元素类型为双字节的字类型,所以偏移量乘以2。

(5) MOV BX,AX。下标一般保存在BX中。

5、跳转排序

DSEG SEGMENT

BUFFER DB 81,89,12

DSEG ENDS

CSEG SEGMENT

ASSUME CS:CSEG,DS:DSEG

START:MOV AX,DSEG

MOV DS,AX

MOV SI,OFFSET BUFFER

MOV AL,[SI]

MOV BL,[SI+1]

MOV CL,[SI+2]

CMP AL,BL

JAE NEXT1

XCHG AL,BL

NEXT1:CMP AL,CL

JAE NEXT2

XCHG AL,CL

NEXT2:CMP BL,CL

JAE NEXT3

XCHG BL,CL

NEXT3:MOV [SI],AL

MOV [SI+1],BL

MOV [SI+2],CL

MOV AH,4CH

INT 21H

CSEG ENDS

END START

注意:

(1) CMP AL,BL。无符号数,相当于执行AL-BL,如果AL大于BL,则CF为0;否则CF为1。

(2) JAE NEXT1。CF为0时跳转,也就是AL大于BL时跳转。

你可能感兴趣的:(解析)