汇编语言王爽第二版-课后答案以及解析

检测点1.111个CPU的寻址能力为8KB,那么它的地址总线的宽度为 13位。
(21KB的存储器有 1024 个存储单元,存储单元的编号从 01023 。
(31KB的存储器可以存储 81922^13) 个bit, 1024个Byte。
(41GB是 10737418242^30) 个Byte、1MB是 10485762^20) 个Byte、1KB是 10242^10)个Byte。
(5808080888029680386的地址总线宽度分别为16根、20根、24根、32根,则它们的寻址能力分别为: 64 (KB)、 1 (MB)、 16 (MB)、 4 (GB)。
(68080808880868028680386的数据总线宽度分别为8根、8根、16根、16根、32根。则它们一次可以传送的数据为: 1 (B)、 1 (B)、 2 (B)、 2 (B)、 4 (B)。
(7)从内存中读取1024字节的数据,8086至少要读 512 次,80386至少要读 256 次。
(8)在存储器中,数据和程序以 二进制 形式存放。
 
解题过程:
(11KB=1024B,8KB=1024B*8=2^N,N=13。
(2)存储器的容量是以字节为最小单位来计算的,1KB=1024B。
(38Bit=1Byte,1024Byte=1KB(1KB=1024B=1024B*8Bit)。
(41GB=1073741824B(即2^301MB=1048576B(即2^201KB=1024B(即2^10)。
(5)一个CPU有N根地址线,则可以说这个CPU的地址总线的宽度为N。这样的CPU最多可以寻找2的N次方个内存单元。(一个内存单元=1Byte)。
(68根数据总线一次可以传送8位二进制数据(即一个字节)。
(78086的数据总线宽度为16根(即一次传送的数据为2B)1024B/2B=512,同理1024B/4B=256。
(8)在存储器中指令和数据没有任何区别,都是二进制信息。
检测点 2.1
(1) 写出每条汇编指令执行后相关寄存器中的值。
mov ax,62627   AX=F4A3H 
mov ah,31H     AX=31A3H 
mov al,23H     AX=3123H 
add ax,ax      AX=6246H 
mov bx,826CH   BX=826CH 
mov cx,ax      CX=6246H 
mov ax,bx      AX=826CH 
add ax,bx      AX=04D8H 
mov al,bh      AX=0482H 
mov ah,bl      AX=6C82H 
add ah,ah      AX=D882H 
add al,6       AX=D888H 
add al,al      AX=D810H 
mov ax,cx      AX=6246H
检测点2.1
(2) 只能使用目前学过的汇编指令,最多使用4条指令,编程计算24次方。 
mov  ax,2         AX=2 
add  ax,ax        AX=4 
add  ax,ax        AX=8 
add  ax,ax        AX=16 
 
检测点2.2
(1) 给定段地址为0001H,仅通过变化偏移地址寻址,CPU的寻址范围为 0010H 到 1000FH 。
 
解题过程:
物理地址=SA*16+EA   
EA的变化范围为0h~ffffh   
物理地址范围为(SA*16+0h)~(SA*16+ffffh)   
现在SA=0001h,那么寻址范围为   
(0001h*16+0h)~(0001h*16+ffffh)   
=0010h~1000fh     
检测点2.2
(2) 有一数据存放在内存20000H单元中,现给定段地址为SA,若想用偏移地址寻到此单元。则SA应满足的条件是:最小为 1001H ,最大为 2000H 。
当段地址给定为 1001H 以下和 2000H 以上,CPU无论怎么变化偏移地址都无法寻到20000H单元。
 
 
解题过程:
物理地址=SA*16+EA   
20000h=SA*16+EA   
SA=(20000h-EA)/16=2000h-EA/16   
EA取最大值时,SA=2000h-ffffh/16=1001h,SA为最小值   
EA取最小值时,SA=2000h-0h/16=2000h,SA为最大值 
 
检测点2.3
下面的3条指令执行后,cpu几次修改IP?都是在什么时候?最后IP中的值是多少? 
mov ax,bx 
sub ax,ax 
jmp ax 
 
答:一共修改四次
第一次:读取mov ax,bx之后 
第二次:读取sub ax,ax之后 
第三次:读取jmp ax之后 
第四次:执行jmp ax修改IP 
最后IP的值为0000H,因为最后ax中的值为0000H,所以IP中的值也为0000H  
检测点3.1
(1)  在DEBUG中,"D 0:0 lf" 查看内存,结果如下: 
0000:0000 70 80 F0 30 EF 60 30 E2-00 80 80 12 66 20 22 60 
0000:0010 62 26 E6 D6 CC 2E 3C 3B-AB BA 00 00 26 06 66 88 
下面的程序执行前,AX=0,BX=0,写出每条汇编指令执行完后相关寄存器中的值
mov ax,1
mov ds,ax
mov ax,[0000]  ax= 2662H 
mov bx,[0001]  bx= E626H 
mov ax,bx      ax= E626H 
mov ax,[0000]  ax= 2662H 
mov bx,[0002]  bx= D6E6H 
add ax,bx      ax= FD48H 
add ax,[0004]  ax= 2C14H 
mov ax,0       ax=   0   
mov al,[0002]  ax= 00e6H 
mov bx,0       bx=   0   
mov bl,[000c]  bx= 0026H 
add al,bl      ax= 000CH 
检测点3.1 
(2) 内存中的情况如图3.6所示
各寄存器的初始值:cs=2000h,ip=0,ds=1000h,ax=0,bx=0;
检测点3.21)补全下面的程序,使其可以将10000H-1000FH中的8个字,逆序拷贝到20000H-2000FH中。
mov ax,1000H 
mov ds,ax 
mov ax,2000H 
mov ss,ax    
mov sp,10h   
push [0] 
push [2] 
push [4] 
push [6] 
push [8] 
push [A] 
push [C] 
push [E] 
检测点3.22)补全下面的程序,使其可以将10000H-1000FH中的8个字,逆序拷贝到20000H-2000FH中。 
mov ax,2000H 
mov ds,ax 
mov ax,1000H
mov ss,ax   
mov sp,0    
pop [e] 
pop [c] 
pop [a] 
pop [8] 
pop [6] 
pop [4] 
pop [2] 
pop [0]  
检测点6.11)下面的程序实现依次用内存0:0~0:15单元中的内容改写程序中的数据,完成程序:
assume cs:codesg
codesg segment
        dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
start:  mov ax,0
        mov ds,ax
        mov bx,0
        mov cx,8
    s:  mov ax,[bx]
         mov cs:[bx],ax
        add bx,2
        loop s
        mov ax,4c00h
        int 21h
codesg ends
end start
检测点6.12)下面的程序实现依次用内存0:0~0:15单元中的内容改写程序中的数据,数据的传送用栈来进行。栈空间设置在程序内。完成程序:
assume cs:codesg
codesg segment
        dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
        dw 0,0,0,0,0,0,0,0,0,0
start:  mov ax, codesg ;或mov ax, cs
        mov ss,ax
        mov sp, 24h    ;或mov sp, 36     ;(第一版填1ah或26)
        mov ax,0
        mov ds,ax
        mov bx,0
        mov cx,8
    s:  push [bx]
         pop cs:[bx]   ;或 pop ss:[bx]
        add bx,2 
        loop s
        mov ax,4c00h
        int 21h
codesg ends
end start
(1)程序如下。
assume cs:code
data segment
   dw 2 dup (0)
data ends
code segment
  start: mov ax,dtat
         mov ds,ax
         mov bx,0
         jmp word ptr [bx+1]
code ends
end start
若要使jmp指令执行后,CS:IP指向程序的第一条指令,在data段中应该定义哪些数据?
 
答案①db 3 dup (0)
答案②dw 2 dup (0)
答案③dd 0
jmp word ptr [bx+1]为段内转移,要CS:IP指向程序的第一条指令,应设置ds:[bx+1]的字单元(2个字节)存放数据应为0,则(ip)=ds:[bx+1]=0
简单来说就是,只要ds:[bx+1]起始地址的两个字节为0就可以了
 
检测点9.11)程序如下。
assume cs:code
data segment
   dd 12345678h
data ends
code segment
  start: mov ax,data
         mov ds,ax
         mov bx,0
         mov [bx],  bx      ;或mov [bx], word ptr 0     ;或mov [bx], offset start
         mov [bx+2],  cs    ;或mov [bx+2],  cs          ;或mov [bx+2], seg code  
         jmp dword ptr ds:[0]
code ends
end start
补全程序,使用jmp指令执行后,CS:IP指向程序的第一条指令。
 
第一格可填①mov [bx],bx      ②mov [bx],word ptr 0  ③mov [bx],offset start等。
第二格可填①mov [bx+2],cs   ②mov [bx+2],cs         ③mov [bx+2],seg code等。
解析:
jmp dword ptr ds:[0]为段间转移,(cs)=(内存单元地址+2),(ip)=(内存单元地址),要CS:IP指向程序的第一条指令,第一条程序地址cs:0,应设置CS:IP指向cs:0
程序中的mov [bx],bx这条指令,是将ip设置为0 
mov [bx+2],cs,将cs这个段地址放入内存单元 
执行后,cs应该不变,只调整ip为0(ip)=ds:[0]=0
检测点9.13)用Debug查看内存,结果如下:
2000:1000 BE 00 06 00 00 00 ......
则此时,CPU执行指令:
mov ax,2000h
mov es,ax
jmp dword ptr es:[1000h]
后,(cs)= 0006H ,(ip)= 00BEH
 
解析:
jmp dword ptr为段间转移,高位存放段地址,低位存放偏移地址
(cs)=(内存单元地址+2)(ip)=(内存单元地址)
 
根据书P16,对于寄存器AX,AH为高位(1字节为高位),AL为低位(1字节为低位)
推算出(内存单元地址)=00beh,(内存单元地址+2)=0006h
根据书P182,高位存放段地址(2个字节为高位),低位存放偏移地址(2个字节为低位)
(cs)=(内存单元地址+2)(ip)=(内存单元地址)
推算出(cs)=0006h,(ip)=00beh
检测点9.2
补全编程,利用jcxz指令,实现在内存2000H段中查找第一个值为0的字节,找到后,将它的偏移地址存储在dx中。
assume cs:code
code segment
 start: mov ax,2000h
        mov ds,ax
        mov bx,0
     s: mov ch,0   
        mov cl,[bx]
        jcxz ok        ;当cx=0时,CS:IP指向OK
        inc bx     
        jmp short s
    ok: mov dx,bx
        mov ax ,4c00h
        int 21h
code ends
end start
检测点9.3
补全编程,利用loop指令,实现在内存2000H段中查找第一个值为0的字节,找到后,将它的偏移地址存储在dx中。
assume cs:code
code segment
start:  mov ax,2000h
        mov ds,ax
        mov bx,0
      s:mov cl,[bx]
        mov ch,0
        inc cx     
        inc bx
        loop s
     ok:dec bx
        mov dx,bx
        mov ax,4c00h
        int 21h
code ends
end start
 
 
书P101,执行loop s时,首先要将(cx)1。
“loop 标号”相当于
dec cx
if((cx)0) jmp short 标号
检测点10.1
补全程序,实现从内存10000000处开始执行指令。
assume cs:code
stack segment
     db 16 dup (0)
stack ends
code segment
start:   mov ax,stack
     mov ss,ax
     mov sp,16
     mov ax, 1000h
     push ax
     mov ax,   0  
     push ax
     retf
code ends
end start
 
 
执行reft指令时,相当于进行:
pop ip
pop cs
根据栈先进后出原则,应先将段地址cs入栈,再将偏移地址ip入栈。
 
检测点10.2
下面的程序执行后,ax中的数值为多少?
内存地址    机器码      汇编指令     执行后情况
1000:0     b8 00 00     mov ax,0     ax=0 ip指向1000:3
1000:3     e8 01 00     call s       pop ip ip指向1000:7
1000:6     40           inc ax
1000:7     58         s:pop ax       ax=6
 
用debug进行跟踪确认,“call 标号”是将该指令后的第一个字节偏移地址入栈,再转到标号处执行指令。
 
assume cs:code
code segment
start:   mov ax,0
     call s
     inc ax
s:   pop ax
     mov ax,4c00h
     int 21h
code ends
end start
 
检测点10.3
下面的程序执行后,ax中的数值为多少?
内存地址   机器码           汇编指令            执行后情况
1000:0    b8 00 00          mov ax,0           ax=0,ip指向1000:3
1000:3    9a 09 00 00 10    call far ptr s     pop cs,pop ip,ip指向1000:9
1000:8    40                inc ax
1000:9    58                s:pop ax           ax=8h
                            add ax,ax          ax=10h
                            pop bx             bx=1000h
                            add ax,bx          ax=1010h
 
用debug进行跟踪确认,“call far ptr s”是先将该指令后的第一个字节段地址cs=1000h入栈,再将偏移地址ip=8h入栈,最后转到标号处执行指令。
出栈时,根据栈先进后出的原则,先出的为ip=8h,后出的为cs=1000h
检测点10.4
下面的程序执行后,ax中的数值为多少?
内存地址   机器码        汇编指令       执行后情况
1000:0     b8 06 00      mov ax,6       ax=6,ip指向1000:3
1000:3     ff d0         call ax        pop ip,ip指向1000:6
1000:5     40            inc ax
1000:6     58            mov bp,sp      bp=sp=fffeh
                         add ax,[bp]    ax=[6+ds:(fffeh)]=6+5=0bh
 
用debug进行跟踪确认,“call ax(16位reg)”是先将该指令后的第一个字节偏移地址ip入栈,再转到偏移地址为ax(16位reg)处执行指令。
 检测点10.51)下面的程序执行后,ax中的数值为多少?
assume cs:code
stack segment
     dw 8 dup (0)
stack ends
code segment
start:   mov ax,stack
     mov ss,ax
     mov sp,16
     mov ds,ax
     mov ax,0
     call word ptr ds:[0eh]
     inc ax
     inc ax
     inc ax
     mov ax,4c00h
     int 21h
code ends
end start
 
推算:
执行call word ptr ds:[0eh]指令时,先cs入栈,再ip=11入栈,最后ip转移到(ds:[0eh])(ds:[0eh])=11h,执行inc ax……最终ax=3
 
题中特别关照别用debug跟踪,跟踪结果不一定正确,但还是忍不住去试试,看是什么结果。
根据单步跟踪发现,执行call word ptr ds:[0eh]指令时,显示ds:[0eh]065D。
ds:0000~ds:0010不是已设置成stack数据段了嘛,不是应该全都是0的嘛。
于是进行了更详细的单步跟踪,发现初始数据段中数据确实为0,但执行完mov ss,ax;mov sp,16这两条指令后,数据段中数据发生改变。这是为什么呢?中断呗~~~~
检测点10.52)下面的程序执行后,ax和bx中的数值为多少?
assume cs:codesg
stack segment
    dw 8 dup(0)
stack ends
codesg segment
start:
    mov ax,stack
    mov ss,ax
    mov sp,10h
    mov word ptr ss:[0],offset s ;(ss:[0])=1ah
    mov ss:[2],cs                ;(ss:[2])=cs
    call dword ptr ss:[0]        ;cs入栈,ip=19h入栈,转到cs:1ah处执行指令
                                 ;(ss:[4])=cs,(ss:[6])=ip
    nop
s:  mov ax,offset s              ;ax=1ah
    sub ax,ss:[0ch]              ;ax=1ah-(ss:[0ch])=1ah-19h=1
    mov bx,cs                    ;bx=cs=0c5bh
    sub bx,ss:[0eh]              ;bx=cs-cs=0
    mov ax,4c00h
    int 21h
codesg ends
end start
检测点11.1
写出下面每条指令执行后,ZF、PF、SF、等标志位的值。
sub al,al     al=0h        ZF=1        PF=1        SF=0 
mov al,1      al=1h        ZF=1        PF=1        SF=0 
push ax       ax=1h        ZF=1        PF=1        SF=0 
pop bx        bx=1h        ZF=1        PF=1        SF=0 
add al,bl     al=2h        ZF=0        PF=0        SF=0 
add al,10     al=12h       ZF=0        PF=1        SF=0 
mul al        ax=144h      ZF=0        PF=1        SF=0
 
检测点涉及的相关内容:
ZF是flag的第6位,零标志位,记录指令执行后结果是否为0,结果为0时,ZF=1
PF是flag的第2位,奇偶标志位,记录指令执行后结果二进制中1的个数是否为偶数,结果为偶数时,PF=1
SF是flag的第7位,符号标志位,记录有符号运算结果是否为负数,结果为负数时,SF=1
add、sub、mul、div 、inc、or、and等运算指令影响标志寄存器
mov、push、pop等传送指令对标志寄存器没影响。
 
检测点11.2
写出下面每条指令执行后,ZF、PF、SF、CF、OF等标志位的值。
              al                 CF    OF    SF    ZF    PF
sub al,al     0h/0000 0000b      0     0     0     1     1
mov al,10h    10h/0010 0000b     0     0     0     1     1
add al,90h    a0h/1010 0000b     0     0     1     0     1
mov al,80h    80h/1000 0000b     0     0     1     0     1
add al,80h    0h/0000 0000b      1     1     0     1     1
mov al,0fch   0fch/1111 1100b    1     1     0     1     1
add al,05h    1h/0000 0001b      1     0     0     0     0
mov al,7dh    7dh/1111 1101b     1     0     0     0     0
add al,0bh    88h/1000 1000b     0     1     1     0     1
 
检测点涉及的相关内容:
ZF是flag的第6位,零标志位,记录指令执行后结果是否为0,结果为0时,ZF=1 
PF是flag的第2位,奇偶标志位,记录指令执行后结果二进制数中1的个数是否为偶数,结果为偶数时,PF=1 
SF是flag的第7位,符号标志位,记录有符号运算结果是否为负数,结果为负数时,SF=1 
CF是flag的第0位,进位标志位,记录无符号运算结果是否有进/借位,结果有进/借位时,SF=1
OF是flag的第11位,溢出标志位,记录有符号运算结果是否溢出,结果溢出时,OF=1
add、sub、mul、div 、inc、or、and等运算指令影响flag
mov、push、pop等传送指令对flag没影响
 
检测点11.3
(1)补全下面的程序,统计F000:032个字节中,大小在[32,128]的数据个数。
     mov ax,0f000h
     mov ds,ax
     mov bx,0      ;ds:bx指向第一个字节
     mov dx,0      ;初始化累加器
     mov cx,32
s:   mov al,[bx]
     cmp al,32     ;32进行比较
     jb s0         ;如果低于al转到s0,继续循环
     cmp al,128    ;128进行比较
     ja s0         ;如果高于al转到s0,继续循环
     inc dx
s0:  inc bx
     loop s
 
[32,128]是闭区间,包括两端点的值
(32,128)是开区间,不包括两端点的值
检测点11.3
(2)补全下面的程序,统计F000:032个字节中,大小在(32,128)的数据个数。
     mov ax,0f000h
     mov ds,ax
     mov bx,0      ;ds:bx指向第一个字节
     mov dx,0      ;初始化累加器
     mov cx,32
s:   mov al,[bx]
     cmp al,32      ;32进行比较
     jna s0        ;如果不高于al转到s0,继续循环
     cmp al,128    ;128进行比较
     jnb s0        ;如果不低于al转到s0,继续循环
     inc dx
s0:  inc bx
     loop s
 
[32,128]是闭区间,包括两端点的值
(32,128)是开区间,不包括两端点的值
 
检测点11.4
下面指令执行后,(ax)= 45h
mov ax,0
push ax
popf
mov ax,0fff0h
add ax,0010h
pushf
pop ax
and al,11000101B
and ah,00001000B
 
推算过程:
popf后,标志寄存器中,本章节介绍的那些标志位都为0(但是此时标志寄存器并不是所有位置都为0,这个不用关心,没学过的位置用*先代替),向下进行,那么pushf将计算后的当时状态的标志寄存器入栈,然后pop给ax,这是ax是寄存器的值(这个值中包含了我们的*号),接下来就是对那些没有学过的标志位的屏蔽操作,这就是最后两条指令的意义所在,将不确定的位置都归0,那么只剩下我们能够确定的位置了,所以,结果就可以推理出来了。
mov ax,0  
push ax  
popf  
mov ax,0fff0h  
add ax,0010h  
pushf
pop ax               0  0  0  0  of df if tf sf zf 0  af 0  pf 0  cf
                     0  0  0  0  0  0  *  *  0  1  0  *  0  1  0  1
                     ax=flag=000000** 010*0101b
and al,11000101B     al=01000101b=45h
and ah,00001000B     ah=00000000b=0h
 
检测点12.1
(1)用debug查看内存,情况如下:
0000:0000  68 10 A7 00 8B 01 70 00-16 00 9D 03 8B 01 70 003号中断源对应的中断处理程序入口的偏移地址的内存单位的地址为: 0070:018b
 
检测点涉及相关内容:
一个表项存放一个中断向量,也就是一个中断处理程序的入口地址,这个入口地址包括段地址和偏移地址,一个表项占两个字,高地址存放段地址,低地址存放偏移地址
 
检测点12.1
(2)
存储N号中断源对应的中断处理程序入口的偏移地址的内存单元的地址为: 4N
存储N号中断源对应的中断处理程序入口的段地址的内存单元的地址为: 4N+2
 
 
检测点涉及相关内容:
一个表项存放一个中断向量,也就是一个中断处理程序的入口地址,这个入口地址包括段地址和偏移地址,一个表项占两个字,高地址存放段地址,低地址存放偏移地址
检测点13.1
 
7ch中断例程如下:
lp:  push bp
     mov bp,sp
     dec cx
     jcxz lpret
     add [bp+2],bx
lpret:   pop bp
     iret
 (1)在上面的内容中,我们用7ch中断例程实现loop的功能,则上面的7ch中断例程所能进行的最大转移位移是多少?
 
最大位移是FFFFH
检测点13.1
(2)7ch中断例程完成jmp near ptr s指令功能,用bx向中断例程传送转移位移。
 
应用举例:在屏幕的第12行,显示data段中以0结尾的字符串。
assume cs:code
data segment
     db 'conversation',0
data ends
code segment
start:
     mov ax,data
     mov ds,ax
     mov si,0
     mov ax,0b800h
     mov es,ax
     mov di,12*160
s:   cmp byte ptr [si],0
     je ok
     mov al,[si]
     mov es:[di],al
     inc si
     add di,2
     mov bx,offset s-offset ok
     int 7ch
ok:  mov ax,4c00h
     int 21h
code ends
end start
 
jmp near ptr s指令的功能为:(ip)=(ip)+16位移,实现段内近转移
 
assume cs:code  
code segment 
start:
mov ax,cs 
mov ds,ax 
mov si,offset do0                ;设置ds:si指向源地址 
mov ax,0 
mov es,ax 
mov di,200h                      ;设置es:di指向目标地址 
mov cx,offset do0end-offset do0  ;设置cx为传输长度 
cld                              ;设置传输方向为正 
rep movsb 
mov ax,0 
mov es,ax 
mov word ptr es:[7ch*4],200h 
mov word ptr es:[7ch*4+2],0      ;设置中断向量表 
mov ax,4c00h 
int 21h 
do0:
     push bp
mov bp,sp
     add [bp+2],bx                    ;ok的偏移地址+bx得到s的偏移地址
pop bp
iret
mov ax,4c00h 
int 21h 
do0end:
     nop
code ends
end start
检测点13.2
判断下面说法的正误:
(1)我们可以编程改变FFFF:0处的指令,使得CPU不去执行BIOS中的硬件系统检测和初始化程序。
 
答:错误,FFFF:0处的内容无法改变。
 
检测点13.2
判断下面说法的正误:
(2)int 19h中断例程,可以由DOS提供。
 
答:错误,先调用int 19h,后启动DOS。
检测点14.1 读取写入CMOS RAM单元内容
(1)编程,读取CMOS RAM的2号单元内容。
 
assume cs:code
code segment
start:  mov al,2        ;赋值al
        out 70h,al      ;将al送入端口70h
        in al,71h       ;从端口71h处读出单元内容
        mov ax,4c00h
        int 21h
code ends
end start
检测点14.12)编程,向CMOS RAM的2号单元写入0。
 
assume cs:code
code segment
start:  mov al,2        ;赋值al
        out 70h,al      ;将al送入端口70h
        mov al,0        ;赋值al
        out 71h,al      ;向端口71h写入数据al
        mov ax,4c00h
        int 21h
code ends
end start
编程,用加法和移位指令计算(ax)=(ax)*10
提示:(ax)*10=(ax)*2+(ax)*8
 
assume cs:code
code segment
start:  mov bx,ax
        shl ax,1   ;左移1(ax)=(ax)*2
        mov cl,3
        shl bx,cl       ;左移3(bx)=(ax)*8
        add ax,bx       ;(ax)=(ax)*2+(ax)*8
        mov ax,4c00h
        int 21h
code ends
end start
 
;应用举例:计算ffh*10
assume cs:code
code segment
start:  mov ax,0ffh
        mov bx,ax
        shl ax,1   ;左移1(ax)=(ax)*2
        mov cl,3
        shl bx,cl       ;左移3(bx)=(ax)*8
        add ax,bx       ;(ax)=(ax)*2+(ax)*8
        mov ax,4c00h
        int 21h
code ends
end start
 
PS:
左移1位,N=(N)*2
左移2位,N=(N)*4
左移3位,N=(N)*8
左移4位,N=(N)*16
左移5位,N=(N)*32
  • 30
    点赞
  • 152
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
第1章 基础知识 1.1 机器语言 1.2 汇编语言的产生 1.3 汇编语言的组成 1.4 存储器 1.5 指令和数据 1.6 存储单元 1.7 CPU对存储器的读写 1.8 地址总线 1.9 数据总线 1.10 控制总线 1.11 内存地址空间(概述) 1.12 主板 1.13 接口卡 1.14 各类存储器芯片 1.15 内存地址空间 第2章 寄存器 2.1通用寄存器 2.2字在寄存器中的存储 2.3几条汇编指令 2.4物理地址 2.516位结构的CPU 2.68086CPU给出物理地址的方法 2.7“段地址×16+偏移地址=物理地址” 的本质含义 2.8段的概念 2.9段寄存器 2.10CS和IP 2.11修改CS、IP的指令 2.12代码段 实验1查看CPU和内存,用机器指令 和汇编指令编程 第3章寄存器(内存访问) 3.1内存中字的存储 3.2DS和(address) 3.3字的传送 3.4mov、add、sub指令 3.5数据段 3.6栈 3.7CPU提供的栈机制 3.8栈顶超界的问题 3.9push、pop指令 3.10栈段 实验2用机器指令和汇编指令编程 第4章第一个程序 4.1一个源程序从写出到执行的过程 4.2源程序 4.3编辑源程序 4.4编译 4.5连接 4.6以简化的方式进行编译和连接 4.71.exe的执行 4.8谁将可执行文件中的程序装载进入 内存并使它运行? 4.9程序执行过程的跟踪 实验3编程、编译、连接、跟踪 第5章(BX)和loop指令 5.1(BX) 5.2Loop指令 5.3在Debug中跟踪用loop指令实现的 循环程序 5.4Debug和汇编编译器masm对指令的 不同处理 5.5loop和(bx)的联合应用 5.6段前缀 5.7一段安全的空间 5.8段前缀的使用 实验4(bx)和loop的使用 第6章 包含多个段的程序 6.1在代码段中使用数据 6.2在代码段中使用栈 6.3将数据、代码、栈放入不同的段 实验5编写、调试具有多个段的程序 第7章更灵活的定位内存地址的 方法 7.1anol和or指令 7.2关于ASCII码 7.3以字符形式给出的数据 7.4大小写转换的问题 7.5(bx+idata) 7.6用(bx+idata)的方式进行数组的 处理 7.7SI和DI 7.8(bx+si)和(bx+di) 7.9(bx+si+idata)和(bx+di+idata) 7.10不同的寻址方式的灵活应用 实验6实践课程中的程序 第8章数据处理的两个基本问题 8.1bx、si、di和bp 8.2机器指令处理的数据在什么地方 8.3汇编语言中数据位置的表达 8.4寻址方式 8.5指令要处理的数据有多长 8.6寻址方式的综合应用 8.7div指令 8.8伪指令dd 8.9dup 实验7寻址方式在结构化数据访问中的 应用 第9章转移指令的原理 9.1操作符offset 9.2jmp指令 9.3依据位移进行转移的jmp指令 9.4转移的目的地址在指令中的jmp 指令 9.5转移地址在寄存器中的jmp指令 9.6转移地址在内存中的jmp指令 9.7jcxz指令 9.8loop指令 9.9根据位移进行转移的意义 9.10编译器对转移位移超界的检测 实验8分析一个奇怪的程序 实验9根据材料编程 第10章CALL和RET指令 10.1ret和retf 10.2call指令 10.3依据位移进行转移的call指令 10.4转移的目的地址在指令中的call 指令 10.5转移地址在寄存器中的call指令 10.6转移地址在内存中的call指令 10.7call和ret的配合使用 10.8mul指令 10.9模块化程序设计 10.10参数和结果传递的问题 10.11批量数据的传递 10.12寄存器冲突的问题 实验10编写子程序 课程设计1 第11章标志寄存器 11.1ZF标志 11.2PF标志 11.3SF标志 11.4CF标志 11.5OF标志 11.6adc指令 11.7sbb指令 11.8cmp指令 11.9检测比较结果的条件转移指令 11.10DF标志和串传送指令 11.11pushf和popf 11.12标志寄存器在Debug中的表示 实验11编写子程序 第12章内中断 12.1内中断的产生 12.2中断处理程序 12.3中断向量表 12.4中断过程 12.5中断处理程序和iret指令 12.6除法错误中断的处理 12.7编程处理0号中断 12.8安装 12.9do0 12.10设置中断向量 12.11单步中断 12.12响应中断的特殊情况 实验12编写0号中断的处理程序 第13章int指令 13.1int指令 13.2编写供应用程序调用的 中断例程 13.3对int、iret和栈的深入理解 13.4BIOS和DOS所提供的 中断例程 13.5BIOS和DOS中断例程的 安装过程 13.6BIOS中断例程应用 13.7DOS中断例程应用 实验13编写、应用中断例程 第14章端口 14.1端口的读写 14.2CMOS RAM芯片 14.3shl和shr指令 14.4CMOS RAM中存储的时间信息 实验14访问CMOS RAM 第15章外中断 15.1接口芯片和端口 15.2外中断信息 15.3PC机键盘的处理过程 15.4编写int 9中断例程 15.5安装新的int 9中断例程 实验15安装新的int 9中断例程 第16章直接定址表 16.1描述了单元长度的标号 16.2在其他段中使用数据标号 16_3直接定址表 16.4程序入口地址的直接定址表 实验16编写包含多个功能子程序的 中断例程 第17章使用BIOS进行键盘输入 和磁盘读写 17.1int 9中断例程对键盘输入的处理 17.2使用int 16h中断例程读取 键盘缓冲区 17.3字符串的输入 17.4应用int 13h中断例程对磁盘 进行读写 实验17编写包含多个功能子程序的 中断例程 课程设计2 综合研究 研究试验1搭建一个精简的C语言 开发环境 研究试验2使用寄存器 研究试验3使用内存空间 研究试验4不用main函数编程 研究试验5函数如何接收不定数量的 参数 附注 附注1Intel系列微处理器的3种工作 模式 附注2补码 附注3汇编编译器(masm.exe)对jmp的 相关处理 附注4用栈传递参数 附注5公式证明
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Achou.Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值