十六、数据处理问题的若干补充

来源:互联网 发布:淘宝客服不是人做的 编辑:程序博客网 时间:2024/04/29 03:43

1. 内存单元作为第一个操作数或唯一的操作数时的情形:

    1) 前面讲过当内存访问作为第一个操作数时不能使用之前说过的法则,即使第二个操作数是寄存器也不行;

    2) 这个时候就需要显式指明内存单元的类型了,可以使用byte ptr或word ptr操作符来指明内存单元是字节型的还是字型的;

!注意:这两个操作符是编译器提供的操作符,并不是汇编指令,不能直接一步翻译成二进制码;

    3) 使用的情形:

         i. 首先是第一个操作数必须是内存单元;

         ii. 第二个操作数可以是寄存器或立即数,不能两个操作数都是内存单元,否则会报错的!

         iii. 如果指令是单操作数时也行;

!注意:即使第一个操作数是寄存器而第二个是内存也可以使用,但是不建议这样做,因为这种情况是可以自动推断的,不要多此一举;

    4) 示例:

assume cs:codecode segmentmovbyte ptr [bx], 12addword ptr [3FH + bp], cxsubbyte ptr [bp][si][9H], clandword ptr 0FCH[bx], 1001Borbyte ptr [bp + 9], bhincword ptr [bx]movax, 4C00Hint21Hcode endsend
!注意:还是不能将[立即数]作为第一个操作数,编译器会将其理解成一个立即数看待的!


4. 除法指令div:

    1) 可以把div看做是mul的逆运算,因此div也有两种类型,分别对应着mul的两种类型;

    2) 对应于字节型的mul,div的运行方式是,将被除数放在ax(mul的结果),除数放在8位寄存器或内存中,商默认存放在al中(mul的第一个默认乘数),而余数放在ah中;

    3) 对应于字型的mul,被除数的低位放在ax中高位放在dx中(mul的结果),除数放在16位寄存器或内存中,商默认放在ax中(mul的第一个默认乘数),而余数放在dx中;

    4) div使用方法,先对数据范围进行估计,然后执行上述步骤(即准备被除数和除数),最后直接执行"div 除数"指令即可,结果就保存在相应的寄存器中了;

    5) 实例:1001 / 100和100001 / 100:

assume cs:codecode segmentmovax, 1001movbl, 100divblmovax, 86A1Hmovdx, 1Hmovbx, 100divbxmovax, 4C00Hint21Hcode endsend
运行结果:

*1. 商是0AH,余数是1H

*2. 商是3E8H,余数是1H

5.   定义双字型数据的伪指令——dd:

       a. 即define double word,可以定义双字型数据(32位);

       b. 程序示例——将第一个数除以第二个数的商放在第三个数中:

assume cs:code, ds:datadata segmentdd 100001dw 100dw 100data endscode segmentstart:mov ax, datamov ds, axmov ax, ds:[0]mov dx, ds:[2]div word ptr ds:[4]mov ds:[6], axmov ax, 4c00hint 21hcode endsend start

6.   重复定义数据的伪指令——dup:

       a. 使用规则:db/dw/dd 重复次数 dup (数值列表)

       b. 即将数值列表中的数值重复定义n次,比如:

            db 3 dup (1, 2, 3)

            即将字节型数值1, 2, 3重复定义3次,即定义了1, 2, 3, 1, 2, 3, 1, 2, 3这9个字节数据


7.   一个较长的程序:

       i.   将年份、收入、雇员数、平均收入填入table表中;

       ii.  程序如下:

assume cs:code, ds:datadata segmentdb '1975','1976','1977','1978','1979','1980','1981','1982','1983'    db '1984','1985','1986','1987','1988','1989','1990','1991','1992'    db '1993','1994','1995'    dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514    dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000    dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226    dw 11452,14430,15257,17800data endstable segmentdb 21 dup ('year summ ne ?? ')table endscode segmentstart:mov ax, datamov ds, axmov ax, tablemov ss, axmov bx, 0mov si, 168mov bp, 0mov cx, 21s:;done yearmov ax, [bx + 0]mov[bp + 0], axmov ax, [bx + 2]mov [bp + 2], ax;done nmov ax, [si]mov [bp + 10], ax;done summov ax, [bx + 84]mov [bp + 5], axmov dx, [bx + 86]mov [bp + 7], dx;done avgdiv word ptr [bp + 10]mov [bp + 13], axadd bx, 4add si, 2add bp, 10hloop smov ax, 4c00hint 21hcode endsend start

              iii. 程序运行结果如下:

                   


原创粉丝点击