汇编-例子解析(一)

 

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号功能说明

 汇编-例子解析(一)_第1张图片

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时跳转。

你可能感兴趣的:(汇编,buffer,byte)