【汇编语言课程】 知识点+易错题 吐血整理(中)

【汇编语言课程】 知识点+易错题 吐血整理(中)

文章目录

    • 【汇编语言课程】 知识点+易错题 吐血整理(中)
      • 七、更灵活的定位内存地址的方法
      • 八、数据处理的两个基本问题
      • 九、转移指令的原理
      • 十、CALL和RET指令

七、更灵活的定位内存地址的方法

知识点整理:

  1. and指令:逻辑与指令,按位进行与运算。通过该指令可将操作对象的相应位设为0,其他位不变。
  2. or指令:逻辑或指令,按位进行或运算。通过该指令可将操作对象的相应位设为1,其他位不变。
  3. 按照ASCII编码规则进行的编码和解码
  4. ’……‘的方式指明数据是以字符的形式给出的,编译器将把它们转化为相对应的ASCII码
  5. 小写字母的ASCII码值比大写字母的ASCII码值大 20H(and和or操作实现)
  6. [bx+idata]表示一个内存单元,它的偏移地址为(bx)+idata(bx中的数值加上 idata)
  7. mov ax,200[bx]与mov ax,[bx].200与mov ax,[200+bx]等效
  8. [bx+idata]的方式为高级语言实现数组提供了便利机制。
  9. si和di是8086CPU中和bx功能相近的寄存器,si和di不能够分成两个8位寄存器来使用
  10. mov ax,[bx+si]的含义为:(ax) = ((ds)* 16+(bx)+(si)),常用成mov ax,[bx] [si]
  11. [bx+si+idata]用两个变量和一个常量表示地址。
  12. 一般来说,在需要暂存数据的时候,我们都应该使用栈。

易错题:

  1. 编程,将datasg段中每个单词改为大写字母。
    assume cs:codesg,ds:datasg,ss:stacksg
      
    datasg segment
    db	'ibm	'
    db	'dec	'
    db	'dos	'
    db	'vax	'
    datasg ends
      
    stacksg segment	;定义一个段,用来做栈段,容量为16个字节
    dw 0,0,0,0,0,0,0,0
    stacksg ends
      
    codesg segment
      start:mov ax,stacksg
            mov ss,ax
            mov sp,16
            mov ax,datasg
            mov ds,ax
            mov bx,0
            mov cx,4
        
      s0:push	cx
         mov	si, 0
         mov	cx, 3
        
      s:mov	al,[bx+si]
        and	al,11011111b
        mov	[bx+si],al
        inc	si
        loop	s
        
        add	bx, 16
        pop	cx
        loop sO
        
        mov	ax,4c00H
        int	21H
    codesg ends
    end start
    

八、数据处理的两个基本问题

知识点整理:

  1. 使用描述性的符号reg来表示一个寄存器,用sreg表示一个段寄存器。
  2. 在8086CPU中,只有bx,si,di,bp这4个寄存器可以用在"[]"中来进行内存单元的寻址.在[…]中,这4个寄存器可以单个出现,或只能以4种组合出现:bx和si、bx和di、bp和si、bp和di
  3. 只要在[…]中使用寄存器bp,而指令中没有显性地给岀段地址,段地址就默认在ss中。比如下面的指令。
  4. 汇编指令 指令执行前数据的位置
    mov bx,[0] 内存,ds:0单元
    mov bx,ax CPU内部,ax寄存器
    mov bx,1 CPU内部,指令缓冲器
  5. 寻址方式 含义 名称
    [idata] EA=idata; SA=(ds) 直接寻址
    [bx] E A=(bx); S A=(ds) 寄存器间接寻址
    [si] EA=(si);SA=(ds)
    [di] E A=(di); S A=(ds)
    [bp] E A=(bp); S A=(ss)
    [bx+idata] E A=(bx)+idata; S A=(ds) 寄存器相对寻址
    [si+idata] E A=(si)+idata; S A=(ds)
    [di+idata] E A=(di)+idata; S A=(ds)
    [bp+idata] E A=(bp)+idata; S A=(ss)
    [bx+di] E A=(bx)+(di); S A=(ds) 基址变址寻址
    [bp+si] E A=(bp)+(si); S A=(ss)
    [bp+di] E A=(bp)+(di); S A=(ss)
    [bx+si+idata] E A=(bx)+(si)+idata;SA=(ds) 相对基址变址寻址
    [bx+di+idata] EA=(bx)+(di)+idata;SA=(ds)
    [bp+si+idata] E A=(bp)+(si)+idata;SA=(ss)
  6. 在没有寄存器名存在的情况下,用操作符x ptr指明内存单元的长度,x在汇编指令中可以为word或byt
  7. div是除法指令
  8. 被除数:默认放在AX或DX和AX中,如果除数为8位,被除数则为16位, 默认在AX中存放;如果除数为16位,被除数则为32位,在DX和AX中存放,DX存放高16位,AX存放低16位。
  9. 除法结果:如果除数为8位,则AL存储除法操作的商,AH存储除法操作的余数; 如果除数为16位,则AX存储除法操作的商,DX存储除法操作的余数。
  10. div byte ptr ds:[0]
    含义:(al) = (ax)/((ds) *16+0)的商
    (ah) = (ax) / ( (ds) *16+0)的余数
  11. div word ptr es:[0]
    含义:(ax) = [ (dx) *10000H+(ax) ] / ( (es) *16+0)的商
    (dx) = [ (dx) *10000H+(ax) ]/( (es) *16+0)的余数
  12. db定义字节型数据;dw定义字节型数据和字型数据;dd是用来定义dword(double word,双字)型数据的
  13. dup是一个操作符,用来进行数据的重复
  14. db 3 dup (0)
    定义了 3个字节,它们的值都是0,相当于db0,0,0

易错题:

  1. 假设我们用Debug查看内存的结果如下:
    2000: 1000 FF FF FF FF FF FF
    那么指令:
    mov ax,2000H
    mov ds,ax
    mov byte ptr [1000H],1
    将使内存中的内容变为:
    2000:1000 01 FF FF FF FF FF …
    而指令:
    mov ax,2000H
    mov ds,ax
    mov word ptr [1000H],1
    将使内存中的内容变为:
    2000:1000 01 00 FF FF FF FF …

九、转移指令的原理

知识点总结:

  1. 可以修改IP,或同时修改CS和IP的指令统称为转移指令
  2. 只修改IP时,称为段内转移,比如:jmp ax
    同时修改CS和IP时,称为段间转移,比如:jmp 1000:0
  3. 由于转移指令对IP的修改范围不同,段内转移又分为:短转移和近转移。
    短转移IP的修改范围为-128〜127。
    近转移IP的修改范围为-32768〜32767。
  4. 操作符offset的功能是取得标号的偏移地址
  5. jmp为无条件转移指令,可以只修改IP,也可以同时修改CS和IP。
    jmp指令要给出两种信息:
    (1)转移的目的地址
    (2)转移的距离(段间转移、段内短转移、段内近转移)
  6. jmp short 标号(转到标号处执行指令),实现的是段内短转移
  7. jmp near ptr 标号,它实现的是段内近转移
  8. jmp far ptr 标号实现的是段间转移,又称为远转移, 用标号的段地址和偏移地址修改CS和IP
  9. 指令格式:jmp 16位 reg
    功能:(IP)=(16 位 reg)
  10. jmp word ptr 内存单元地址(段内转移)
    功能:从内存单元地址处开始存放着一个字,是转移的目的偏移地址。
  11. jmp dword ptr 内存单元地址(段间转移)
    功能:从内存单元地址处开始存放着两个字,高地址处的字是转移的目的段地址,低地址处是转移的目的偏移地址。
    (CS)=(内存单元地址+2)
    (IP)=(内存单元地址)
  12. jcxz指令为有条件转移指令,所有的有条件转移指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对IP的修改范围都为:-128〜127
  13. jcxz 标号 (如果(cx)=0,转移到标号处执行。
  14. loop指令为循环指令,所有的循环指令都是短转移
  15. loop 标号((cx)=(cx)-l,如果(CX)尹0,转移到标号处执行。
  16. dec指令的功能和inc相反,dec bx进行的操作为:(bx) = (bx) -1
  17. nop为空指令,占一个字节

易错题:

  1. (1) 程序如下。
    assume cs:code 
    
    data segment 
    
    ```
    
    data ends 
    
    code segment 
    
    start: mov ax,data 
    
    mov ds,ax 
    
    mov bx,0 
    
    jmp word ptr [bx+1] 
    
    code ends 
    
    end start 
    
    若要使程序中的 jmp 指令执行后,CS:IP 指向程序的第一条指令,在 data 段中应该定义哪些数据?
    db 0,0,0
  2. 程序如下。
    assume cs:code,ds:data 
    
    data segment 
    
    dd 12345678hdata ends 
    
    code segment 
    
    start: mov ax,data 
    
    mov ds,ax 
    
    mov bx,0 
    
    mov [bx],** /bx 
    mov [bx+2],** /cs
    
    jmp dword ptr ds:[0] 
    
    code ends 
    
    end start 
    
    补全程序,使 jmp 指令执行后,CS:IP 指向程序的第一条指令。
  3. 用 Debug 查看内存,结果如下:
    2000:1000 BE 00 06 00 00 00 …
    则此时,CPU 执行指令:
    mov ax,2000H 
    
    mov es,ax 
    
    jmp dword ptr es:[1000H] 
    
    后,(CS)=? , (IP)=?
    解:CS=0006H,IP=00BEH
  4. 重点!!! 编程:在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串’welcome to masm!'。
    解:
   assume cs:code 

   data segment 

   db 'welcome to masm!' 

   data ends 

   code segment 

   start: mov ax,data 

   mov ds,ax 

   mov ax,0b800h 

   mov es,ax 

   mov si,0 

   mov di,10*160+80 ;第十行中间 

   mov cx,16 

   s1: mov al,ds:[si] 

   mov ah,00000010B ;绿色 

   mov es:[di],ax 

   inc si 

   inc di 

   inc di 

   loop s1 

   mov si,0 

   mov di,11*160+80 ;第十一行中间 

   mov cx,16 

   s2: mov al,ds:[si] 

   mov ah,00100100B ;绿底红色 

   mov es:[di],ax 

   inc si 

   inc di 

   inc di 

   loop s2 

   mov si,0 

   mov di,12*160+80 ;第十二行中间 

   mov cx,16 

   s3: mov al,ds:[si] 

   mov ah,01110001B ;白底蓝色 

   mov es:[di],ax 

   inc si 

   inc diinc di 

   loop s3 

   mov ax,4c00h 

   int 21h ;如果要看到完整的显示请输入:“-g 4c”,即立即运行到此条指令 

   code ends 

   end start 

   注:此程序如果利用后面所学知识,可以将三次显示嵌套简化为一次。 

十、CALL和RET指令

知识点总结:

  1. call和ret指令都是转移指令,它们都修改IP,或同时修改CS和IP
  2. ret指令用栈中的数据,修改IP的内容,从而实现近转移;
    retf指令用栈中的数据,修改CS和IP的内容,从而实现远转移。
  3. CPU执行call指令时,进行两步操作:
    (1) 将当前的IP或CS和IP压入栈中;
    (2) 转移。
  4. call指令不能实现短转移,除此之外,call指令实现转移的方法和jmp指令的原理相 同
  5. call 标号(将当前的IP压栈后,转到标号处执行指令)
  6. call far ptr 标号实现的是段间转移。
  7. call 16位reg
    功能:
    (sp)=(sp)-2
    ((ss)* 16+(sp))=(IP) (IP)=(16 位 reg)
  8. call word ptr 内存单元地址
    相当于进行:
    push ip
    jmp word ptr内存单元地址
  9. call dword ptr 内存单元地址
    push CS
    push IP
    jmp dword ptr内存单元地址
  10. 子程序的框架如下。
    标号:
    ​ 指令
    ​ ret
  11. mul是乘法指令;只能是相同位数的数相乘;数默认放在ax中;8位乘法,结果默认放在AX中;16位乘法,结果高位默 认在DX中存放,低位在AX中放。
  12. call与ret指令共同支持了汇编语言编程中的模块化设计
  13. 在子程序的开始将子程序中所有用到的寄存器中的内容 都保存起来,在子程序返回前再恢复。可以用栈来保存寄存器中的内容。

易错题整理:

  1. 下面的程序执行后,ax 中的数值为多少?
   内存地址 机器码 汇编指令 
   1000:0   b8 00 00       	 mov ax,0
   1000:3   e8 01 00   		 call s 
   1000:6   40               inc ax 
   1000:7   58               s:pop ax 

解:ax=6 ;指行完call s后ip=6,压入栈
2. 下面的程序执行后,ax 中的数值为多少?

   内存地址   机器码                   汇编指令 
   1000:0      b8 00 00               mov ax,0 
   1000:3      9a 09 00 00 10    	  call far ptr s 
   1000:8      40                     inc ax 
   1000:9      58                     s:pop ax 
   ​                                   add ax,ax 
   ​                                   pop bx 
   ​     							  add ax,bx 

解:ax=1010h;执行完call far ptr s后cs=1000h先入栈,ip=8后入栈
3. 下面的程序执行后,ax 中的数值为多少?

   内存地址 		机器码 			汇编指令 
   1000:0		 b8 06 00 		mov ax,6 
   1000:2		 ff d0 			call ax 
   1000:5		 40			    inc ax 
   1000:6 				 		mov bp,sp 
   ​                      		add ax,[bp] 

解:ax=11;执行完call ax后,ip=5入栈,程序跳转到mov bp,sp
执行完add ax,[bp]后 ax = 6+5 = 11
5.

   mov sp,10h
   mov ax,0123h
   mov ds:[0],ax
   mov word ptr ds: [2],0
   call dword ptr ds:[0]

执行后,(CS)=0, (IP)=0123H, (sp)=0CH
6. 下面的程序执行后,ax 中的数值为多少?

 assume cs:codestack 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 

解:ax=3

  1. 下面的程序执行后,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 word ptr ss:[0],offset s 

   mov ss:[2],cs 

   call dword ptr ss:[0] 

   nop 

   s: mov ax,offset s 

   sub ax,ss:[0cH] 

   mov bx,cs 

   sub bx,ss:[0eH] 

   mov ax,4c00h 

   int 21h 

   code endsend start 

解:ax=1,bx=0

你可能感兴趣的:(笔记,汇编语言)