汇编语言(王爽第三版)检测点16

检测点16.1

       下面的程序将code段中a处的8个数据累加,结果存储到b处的双字中,补全程序。

assume cs:code

code segment

    a dw 1, 2, 3, 4, 5, 6, 7, 8

    b dd 0

start: mov si, 0

        mov cx, 8

    s:  mov ax, a[si]

        add word ptr b[0], ax

        adc word ptr b[2], 0

        add si, 2

        loop s

       

        mov ax, 4c00H

        int 21H

code ends

end start

程序分析:

【1】a代表了code段的首地址code:00,由于dw,也代表了a开始的这一小段内存都是按照字单元存储的。从code:[0]~code:[15],也就是,a[0]~a[15];a[si]代表了从code:00开始的偏移量为si的内存单元。此内存单元是字单元,故si的偏移量是2个字节。

【2】b代表了code段中紧邻a段地址的code:[16](首地址),一个双字的单元,它存储位置是code:[16]~code:[19],也就是b[0]~b[3];剩下的空间都是真正的CPU执行的代码了。

【3】mov ax, a[si]代码含义:将偏移量为si的段地址(或内存段首地址)为a的内存单元按字单元送入到ax中。

【4】add word ptr b[0], ax,代码含义:将ax值与b标号的低16位做加法,结果存储在b标号的低16位中;此时b代表的是双字单元,如果add b, ax;编译器肯定报错,因为它们的类型不匹配。此处必须指定b[0]是按照字单元作为存储结构的。

【5】adc word ptr b[2], 0;代码含义:带进位加法,将0与上一指令中的CF值相加,结果存储在b的高16位单元中。目的:防止低16位值产生进位。同理:此处必须指定b[2]是按照字单元作为存储结构的。这个实例就是高位不溢出加法的套路。对于无符号数加法它的最大允许范围是(0000 0000H~FFFF FFFFH):0~4294967295

【6】add si, 2;代码含义:si的偏移量,由于a的偏移量是按照字单元偏移,故si为2个字节的偏移量。

检测点16.2

下面的程序将code段中a处的8个数据累加,结果存储到b处的双字中,补全程序。

assume cs:code, ds:data

data segment

    a db 1,2,3,4,5,6,7,8

    b dw 0

data ends

code segment

start: mov ax,data

        mov ds,ax

        mov si,0

        mov cx, 8

    s:  mov al, a[si]       ;a[si]代表的是一个字节。

        mov ah, 0           ;ah置零,防止高位不为零

        add b, ax

        inc si

        loop s

       

        mov ax,4c00h

        int 21h

code ends

end start

程序分析:

【1】即使在assume这个伪指令中将ds和data联系在一起(C语言的全局声明意思)。如果没有将data的段地址赋值给ds,那么[si]寻址的内存单元是错误的,并不是ds:[si]或a[si]。

【2】如果在assume中没有ds:data,那么在code段中使用a和b是不可能的。因为a和b在code段是不可以见的。

【3】a[si]代表的是一个字节(它已经代表地址和单元长度了),赋值给ax是错误的,应该赋值给al,别犯这样的低级错误。(ah)=0,是防止高位不为零,al+ah组合成数据就是(ax)。

posted @ 2017-05-21 09:41  筑基2017  阅读(1695)  评论(0编辑  收藏  举报