一、hello实例
DSEG SEGMENT MESSAGE DB 'How do you do',0DH,0AH,24H DSEG ENDS CSEG SEGMENT ASSUME CS:CSEG,DS:DSEG BEGIN: 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 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时跳转。