1 总的来说:压缩BCD和非压缩BCD就是通过十六进制加减法实现十进制加减法。
题目 | 分析 | 结果 |
mov al, 06h sub al, 08h aas (AL)= CF= | 正常06h-08h=00FE AAS判断是:根据AL低四位是否大于9, 若大减去6,=08,AL高四位取缔,然后AH-1=FF | FF08 有进位,故CF=1 (此时辅助标志AF,进位标志CF均改变) |
mov ax, 0605h mov bl, 08h aad div bl (AL)= | AAD能够将AH和AL的东西当做十进制放入AL,这 里即把65这个十进制的十六进制形式41放入AL。 然后再除以08h,其实就是65除以8的值,al=8毫无疑问。 (这里除数是bl,为字节操作数,因此被除数是AX, 故商送al,余数01送ah;如果除数是字操作数, 那么被除数就应该是dx:ax,就是商送ax,余数送dx了) | 8 |
mov al, 07h mov bl, 06h mul bl aam (AX)= | 考察AAM指令应用。 aam既然是非压缩bcd码用来调整乘法结果的指令, 可想而知就是将结果表示为十进制能够表达的形式了, 这里6*7=42,结果就应该是0402了。 | 0402h |
mov al, 85h add al, 29h DAA | 注意这里是压缩bcd码加法调整指令,不要混淆了,它的调整将放入AL中,因此会将原始结果AE调整为:14,并将CF置1. | 14 |
P.S.
[在分析之前问题的基础上,发现了一个很2b的问题,就是dos功能02h和09h显示字符和字符串时,如果后面没有功能能让程序暂停(等待键盘),则dos不会显示出应该显示的东西,可能是显示太快,而无法发现。因此一般,为了看清楚,后面可以,mov ah, 07h; int 21h ;就可以看见显示结果了]
2 首先显示提示信息"input your password please:" 然后等用户输入两位字符的口令,口令中的两个字符存储到变量PASSW中但不显示在屏幕上,用户每按一键则屏幕显示一个*,两个**显示在提示信息的下一行
我写的程序与书上程序区别: | 最终结果: |
1 关于将值赋给passw 我的用法是: mov byte ptr passw, al mov byte ptr passw+1, al 书上用法: mov SI, offset PASSW .... mov [SI], al INC SI mov [SI], al 2 我定义passw时是用Dw,但是书上使用db ?,? Ps:我直接用了一个DW变量,这样存入也没有问题。 但是在输出时,因为结尾没有'$'就会把内存中东西都输出来,直到碰到'$'结尾。因此,如果希望输出一个字符串,一定要保证结尾带有'$'. | NAME example4 DATA SEGMENT msg1 db 'input your password please',0ah,0dh,'$' PASSW db ?,?,'$' DATA ENDS CODE SEGMENT ASSUME DS:DATA, CS:CODE START: ; cannot lose MOV AX, DATA MOV DS, AX XOR AX, AX ; qiao coding mov dx, offset msg1 mov ah, 09h int 21h mov SI, offset PASSW mov ah, 07h int 21h mov [SI], al mov dl, '*' mov ah, 02h int 21h INC SI mov ah, 07h int 21h mov [SI], al mov dl, '*' mov ah, 02h int 21h ; for identification mov dx, offset PASSW mov ah, 09h int 21h MOV AH, 4CH INT 21H CODE ENDS END START |
3 计算S=(23000-(x*y+z))/Z
qiaoData segment x dw 600 y dw 25 z dw -2000 s dw ?,? qiaoData ends sseg segment stack db 80h dup(0) sseg ends qiaoCode segment assume cs:qiaoCode, ds:qiaoData, ss:sseg start: mov ax, qiaoData mov ds,ax mov ax,x imul y mov bx,ax mov cx,dx ; jinwei add mov ax,z cwd add bx,ax adc cx,dx mov ax, 23000 cwd sub ax,bx sbb dx,cx IDIV z mov s,ax mov s+2,dx mov ah, 4ch int 21h qiaoCode ends end start | 几个注意的地方:
|
4
一个答案 | 我的答案 |
name 6.4 qiaoData segment a db 2 b db 9 cc db 8 d db ? qiaoData ends sseg segment stack db 80h dup(0) sseg ends qiaoCode segment assume cs:qiaoCode, ds:qiaoData, ss:sseg start: mov ax, qiaoData mov ds,ax xor ax, ax ;real start mov al, a MUL CC mov bl,4 MUl bl AAM ; mov cl,4 shl ah,cl add al, ah mov dx, ax ; mov al, b MUL al AAM ; mov cl,4 shl ah,cl add al, ah sub al,d das mov d,al mov cl,4 shr al,cl add al,30h mov dl, al mov ah, 2 int 21h mov al,d and al, 0fh add al, 30h mov dl, al; mov ah,2 int 21h mov ah, 07h int 21h mov ah, 4ch int 21h qiaoCode ends end start | name 6.4 qiaoData segment a db 2 b db 9 cc db 8 d db ? qiaoData ends sseg segment stack db 80h dup(0) sseg ends qiaoCode segment assume cs:qiaoCode, ds:qiaoData, ss:sseg start: mov ax, qiaoData mov ds,ax xor ax, ax ;real start mov al, a MUL CC mov bl,4 MUl bl AAM mov dx, ax mov al, b MUL al AAM ; sub ax,dx and ax, 0f0fh ;把多余位置取消 mov cl,4 shl ah,cl add al, ah das mov d,al mov cl,4 shr al,cl add al,30h mov dl, al mov ah, 2 int 21h mov al,d and al, 0fh add al, 30h mov dl, al; mov ah,2 int 21h mov ah, 07h int 21h mov ah, 4ch int 21h qiaoCode ends end start |
这个程序的实现是这样的:
| 我写的跟它的区别是,前期做减法前并不将结果变为 压缩BCD,得到01FD,此时and 0f0fh,边得到 010D,再把这个结果转化为压缩bCD,后面类同。 其实我想最简单的是,前面就用十六进制算法得到0011H=17,然后把这个十六进制转换为十进制输出即可。这里先不讨论。 |