王爽 汇编语言个人疑问汇总第五篇

第九章

实验8 分析一个奇怪的程序

原程序

assume cs:codesg
codesg segment
	
	mov ax,4c00h
	int 21h

start:
	mov ax,0
s:  
	nop ;该指令不会产生任何的效果
	nop ; 该指令不会产生任何的效果
	mov di,offset s ; s标号第一条指令的地址给di
	mov si,offset s2 ;s2标号第一条指令地址给si
	mov ax,cs:[si]   ; cs:[si] 赋值给ax寄存器
	mov cs:[di],ax   ; ax赋值给cs:[di]
s0:
	jmp short s ; 段内短转移,转移到标号处执行指令
s1:  
	mov ax,0
	int 21h
	mov ax,0
s2:
	jmp short s1 ; 段内短转移,转移到标号处执行指令
	nop

codesg ends
end start

程序分析

  • 我们来debug下。
    在这里插入图片描述
  • 我们输入t,在观察cs段寄存器
    在这里插入图片描述

很明显看到偏移地址0008的指令变成了 JMP 0000(nop 只占一个字节, 因此两个 nop 被完全替代)。

毫无疑问就是mov cs:[di],ax 这段代码改变的。

还有个疑问,为什么是JMP 0000呢?mov si,offset s2是指向s2代码段第一条指令的,那么应该是jmp short s1执行s1代码段呀。

mov cs:[di], ax后,可以暂且认为 cs:0008现在指令是 jmp short s1 机器码是EBF6

注意:jmp short是段内短转移,求的是相对位置。F6就是-10, -10F6补码形式(EB代表jmp指令,F6代表了自此偏移地址开始,向前偏移10个字节),所以从0008位置向前偏移10个字节地址是0000

总结

  • jmp short xxx是段内短转移,注意求的是相对位置,这段代码在不同的位置效果也不一样。

实验9 根据材料编程

assume cs:code

data segment
  db 'welcome to masm!'
  db 01110001b ;   白底蓝字 71H
  db 00100100b ;   绿底红字 24H
  db 00000010b ;   黑底绿字 02H 
data ends

stack segment
  dw 8 dup (0)
stack ends

code segment
start: mov ax,data      
       mov ds,ax          ; data段指向ds段寄存器 
       mov ax,stack       
	   
       mov ss,ax          ; stack段指向ss段寄存器
       mov sp,16          
	   
       mov ax,0b800h       
       mov es,ax          ; 显示缓冲区指向es段寄存器

       mov si,06e0h       ; 字符串从哪个位置开始显示

       mov cx,3           ; 循环次数
   s0: mov bx,cx
       mov ah,[bx+15]     ; 读取行的颜色,ax寄存器的高位存颜色; 黑底绿字 02H 、 绿底红字 24H 、白底蓝字 71H
       mov bx,40h         ; 在一行哪个位置开始
	   push cx            ; 外层循环暂存cx,放到栈中
       mov di,0           ;  第0字节开始
       mov cx,16          ; 内循环次数 16,也就是 welcome to masm! 的长度
	   
    s: mov al,[di]        ; 读取字符,ax寄存器的低位存字符
	   mov es:[bx+si],ax  ; 写入字符
       inc di             ; 下一个字节
       add bx,2           ; 下一个字
       loop s             ; 内循环,显示一行的数据
	   
       add si,0a0h        ; next row  下一行,作用就是换行
       pop cx             ; 将栈中数据弹出给cx,外层循环使用
       loop s0            ; 外循环,显示下一行的数据

       mov ax,4c00h       
       int 21h

code ends
end start

第十章

检测点10.2 下面的程序执行后,ax中的数值为多少?

 	 mov ax,0 ;读取此条指令后IP=3
	 
	 call s   ;读取此条指令后IP=6 , 执行call 标号时,相当于 
			   ;push IP  
			   ;jmp near ptr 标号
			   ; 此时将6压入栈
			   ; 下一步转移到s段
	 inc ax
   s: pop ax  ; 取出栈中数据赋值给ax寄存器,为0006H
  • 关于mov ax,0我们IP的值=3,参考书上2.11 修改CS、IP指令就知道了。

检测点10.3 下面的程序执行后,ax中的数值为多少?

内存地址       机器指令	             汇编指令
1000:0	       b8 00 00              mov ax,0           ; 读入这条指令 IP=3
1000:3         9A 09 00 00 10        call far ptr s     ; 读入这条指令 IP=8
                                                        ; call far ptr 标号 时相当于
														; push CS
														; push IP
														; jmp far ptr 标号
1000:8         40                    inc ax             
1000:9         50                    s:pop ax		    ; 按照栈先入后出的特性,第一次pop取出的是IP的值,为8,传送给ax寄存器
                                     add ax,ax  	    ; 8H + 8H = 10H
                                     pop bx		        ; 按照栈先入后出的特性,第二次pop取出的是CS的值,CS的值题目已经给出了,是1000H,传送给bx寄存器
                                     add ax,bx		    ; 1000H + 10H = 1010H

AX = 1010H

  • 关于mov ax,0我们IP的值=3,参考书上2.11 修改CS、IP指令就知道了。

检测点10.4 下面的程序执行后,ax中的数值为多少?

内存地址   机器码        汇编指令       执行后情况

1000:0     b8 06 00      mov ax,6       ; 读入这条指令 IP=3

1000:3     ff d0         call ax        ; 读入这条指令 IP=5
										; call 16位reg 相当于
										;push IP     ,push 5
										;jmp 16位reg ,jmp 6
										
1000:5     40            inc ax         ; 未执行

1000:6     58            mov bp,sp      ; (bp) = (sp)

                         add ax,[bp]    ;相当于add ax,[bp], bp就是sp,sp默认段地址ss,所以即把栈顶元素弹出和AX相加 ,6+5=11H
  • 关于mov ax,6我们IP的值=3,参考书上2.11 修改CS、IP指令就知道了。

posted on 2021-11-04 11:52  愤怒的苹果ext  阅读(37)  评论(0编辑  收藏  举报

导航