汇编语言王爽第4版实验8答案(和你想的不一样)

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

E:\mywork\asm\p906.asm
C:\>edit p906.asm
assume cs:code

code segment

	mov ax,4c00h
	int 21h
start:	
	mov ax,0
s:
	nop		; nop的机器码占一个字节
	nop
	
	mov di, offset s
	mov si, offset s2
	mov ax, cs:[si]
	mov cs:[di],ax
s0:
	jmp short s
s1:
	mov ax,0
	int 21h
	mov ax,0
	
s2:
	jmp short s1
	nop

code ends

end 
C:\>

编译、连接、运行

C:\>debug p906.exe
-u
076A:0000 B8004C	MOV AX,4C00
076A:0003 CD 21		INT 21
076A:0005 B80000	MOV AX,0000
076A:0008 90		NOP
076A:0009 90		NOP
076A:000A BF0800	MOV DI,0008
076A:000D BE2000	MOV SI,0020
076A:0010 2E		CS:
076A:0011 B804		MOV AX,[SI]
076A:0013 2E		CS:
076A:0014 8905		MOV [DI],AX
076A:0016 EBF0		JMP 0008
076A:0018 B80000	MOV AX,0000	
076A:001B CD21		INT 21
076A:001D B80000	MOV AX,0000
076A:0020 EBF6		JMP 0018	; 位移0f6h,取反加1为:10h
076A:0022 90		NOP			;    (-0ah)11110110 00001001 00001010(0ah)
076A:0023 0000		ADD [BX,SI],AL
-q
C:\>

运行说明
在debug中默认会从第1条指令(MOV AX,4C00)运行,无法正常调试。
所以我们使用rip命令,将ip修改为5,从cs:0005处开始执行。调试过程如下图:

汇编语言王爽第4版实验8答案(和你想的不一样)_第1张图片
汇编语言王爽第4版实验8答案(和你想的不一样)_第2张图片

汇编语言王爽第4版实验8答案(和你想的不一样)_第3张图片
单步调试到JMP 0008时,查看内存中的代码如下图所示:
汇编语言王爽第4版实验8答案(和你想的不一样)_第4张图片
从上图可以看到,076A:0008处的机器指令EBF6,汇编指令是:JMP 0000,怎么回事?请看后面的详细分析。

C:\>p906
C:\>

命令行下执行,也可以正常退出,如下图所示:
汇编语言王爽第4版实验8答案(和你想的不一样)_第5张图片
运行分析
先说一下整个运行流程的关键节点(可能和你想象的不一样):
1、执行076A:0016处的汇编指令JMP 0008;
2、执行076A:0008处的机器指令EBF6;
3、执行076A:0000处的汇编指令MOV AX,4C00和INT 21,调用中断结束运行。
详细分析
1、复制cs:0020处的字内容到cs:0008,实际上就是修改了内存cs:0008处内容为EBF6(cs:0020处jmp 18的机器码);
2、顺序执行到076A:0016指令:JMP 0008;
3、执行076A:0008处的内容,机器指令为:EBF6。
机器指令:EBF6,EB表示跳转,偏移量为F6。
此处为关键,有两种算法,看懂这一点,你就通了:
1)用公式算(P180),根据机器指令:EBF6,求标号处的地址
8位位移=标号处的地址-jmp指令后的第一个字节的地址
//推导:
标号处的地址=8位位移+jmp指令后的第一个字节的地址
//看仔细喽:
8位位移:就是偏移量F6
jmp指令后的第一个字节的地址:076A:0008+2=076A:000A,段地址省略,直接取000A
//计算:
标号处的地址=0F6H+000AH=0H
补码:11110110 0F6H
补码:00001010 06H
相加:00000000 0H(高位溢出的1直接舍弃)
计算方法查看:附录2 补码
标号处的地址为0H,即执行CS:0000处的代码。
2)向前跳转反推(看不懂这种就用第1种公式去算)
偏移量为F6,即向前跳转,F6取反加1为0AH,即向前跳转0AH个位移量:
补码:11110110 0F6H
取反:00001001 09H
加一:00001010 0AH(0F6H的绝对值)
jmp指令后的第一个字节的地址:076A:0008+2=076A:000A
从076A:000A向前跳转0AH,即执行076A:0000处的指令。
跳转方法查看:附录3 补汇编语言(masm.exe)对jmp的相关处理。
4、从076A:0000执行汇编指令MOV AX,4C00,调用中断结束程序。
后记
前面使用rip命令来进行调试,原因是代码抄错了:)
正确:

end start

错误:

end 

(全文完)

你可能感兴趣的:(asm,汇编语言,烧脑)