|
发表于 2013-7-26 00:08:15
|
显示全部楼层
检测点9.1
(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.1
(1)程序如下。
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
C:\DOCUME~1\SNUSER>debug jc9-1.exe
-r
AX=0000 BX=0000 CX=0021 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0C3E ES=0C3E SS=0C4E CS=0C4F IP=0000 NV UP EI PL NZ NA PO NC
0C4F:0000 B84E0C MOV AX,0C4E
-t
AX=0C4E BX=0000 CX=0021 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0C3E ES=0C3E SS=0C4E CS=0C4F IP=0003 NV UP EI PL NZ NA PO NC
0C4F:0003 8ED8 MOV DS,AX
-t
AX=0C4E BX=0000 CX=0021 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0C4E ES=0C3E SS=0C4E CS=0C4F IP=0005 NV UP EI PL NZ NA PO NC
0C4F:0005 BB0000 MOV BX,0000
-t
AX=0C4E BX=0000 CX=0021 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0C4E ES=0C3E SS=0C4E CS=0C4F IP=0008 NV UP EI PL NZ NA PO NC
0C4F:0008 891F MOV [BX],BX DS:0000=5678
-t
AX=0C4E BX=0000 CX=0021 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0C4E ES=0C3E SS=0C4E CS=0C4F IP=000A NV UP EI PL NZ NA PO NC
0C4F:000A 8C4F02 MOV [BX+02],CS DS:0002=1234
-t
AX=0C4E BX=0000 CX=0021 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0C4E ES=0C3E SS=0C4E CS=0C4F IP=000D NV UP EI PL NZ NA PO NC
0C4F:000D FF2E0000 JMP FAR [0000] DS:0000=0000
-t
AX=0C4E BX=0000 CX=0021 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0C4E ES=0C3E SS=0C4E CS=0C4F IP=0000 NV UP EI PL NZ NA PO NC
0C4F:0000 B84E0C MOV AX,0C4E
-q
检测点9.1
(3)用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
用debug跟踪,可能会出现如下错误,debug给出的答案是(cs)不变,(ip)=1000h
C:\DOCUME~1\SNUSER>debug
-r es
ES 0BF9
:2000
-e 2000:1000 be 00 06 00 00 00
-a
0BF9:0100 mov ax,2000
0BF9:0103 mov es,ax
0BF9:0105 jmp dword ptr es:[1000]
^ Error
0BF9:0105 jmp dword ptr 2000:1000
0BF9:0108
-r
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0BF9 ES=2000 SS=0BF9 CS=0BF9 IP=0100 NV UP EI PL NZ NA PO NC
0BF9:0100 B80020 MOV AX,2000
-t
AX=2000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0BF9 ES=2000 SS=0BF9 CS=0BF9 IP=0103 NV UP EI PL NZ NA PO NC
0BF9:0103 8EC0 MOV ES,AX
-t
AX=2000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0BF9 ES=2000 SS=0BF9 CS=0BF9 IP=0105 NV UP EI PL NZ NA PO NC
0BF9:0105 E9F80E JMP 1000
-t
AX=2000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0BF9 ES=2000 SS=0BF9 CS=0BF9 IP=1000 NV UP EI PL NZ NA PO NC
0BF9:1000 E475 IN AL,75
出现错误的原因是:
jmp dword ptr es:[1000H]对应的debug下的指令并不是你给出的
jmp dword ptr 2000:[1000H]这样的形式,可以看出,当你写出上述指令后,运行的时候其指令仅仅变成了jmp 1000,缺少了一个指定段地址的指令。
我们可以写一个源程序模拟一下上面的这段程序
assume cs:codesg
data segment
db 0BEH,0,6,0,0,0
data ends
codesg segment
start:
mov ax,data
mov es,ax
jmp dword ptr es:[0H]
codesg ends
end start
上面这个程序,数据地址是程序分配的,不是指定的那个地址,但是,对于我们理解程序运行的整个过程没有影响。下面是debug的信息
-t
AX=1438 BX=0000 CX=001A DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=1428 ES=1428 SS=1438 CS=1439 IP=0003 NV UP EI PL NZ NA PO NC
1439:0003 8EC0 MOV ES,AX
-t
AX=1438 BX=0000 CX=001A DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=1428 ES=1438 SS=1438 CS=1439 IP=0005 NV UP EI PL NZ NA PO NC
1439:0005 26 ES:
1439:0006 FF2E0000 JMP FAR [0000] ES:0000=00BE
-d es:0 f
1438:0000 BE 00 06 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
-t
AX=1438 BX=0000 CX=001A DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=1428 ES=1438 SS=1438 CS=0006 IP=00BE NV UP EI PL NZ NA PO NC
0006:00BE 00F0 ADD AL,DH
我们可以看到,源程序中jmp dword ptr es:[0H] 对应的debug下的汇编指令是
1439:0005 26 ES:
1439:0006 FF2E0000 JMP FAR [0000]
而不是仅仅的一个(JMP 地址)那样的形式,所以,你在debug下的操作本身就是不行的。
另外,此题目的检测目的就是将内存中的数据作为跳转的CS和IP的值来进行跳转。对于给定的一个地址A,A开始的一个字单元是IP,A+2开始的一个字段元是CS。也就是以A为其实地址的内存中,低字单元是IP,高字单元是CS。
如非要在DEBUG中进行操作,可用以下方式:
-e 2000:1000 be 00 06 00 00 00
-a
139A:0100 mov ax,2000
139A:0103 mov es,ax
139A:0105 es:
139A:0106 jmp far [1000]
139A:010A
-u
139A:0100 B80020 MOV AX,2000
139A:0103 8EC0 MOV ES,AX
139A:0105 26 ES:
139A:0106 FF2E0010 JMP FAR [1000]
-r
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=139A ES=139A SS=139A CS=139A IP=0100 NV UP EI PL NZ NA PO NC
139A:0100 B80020 MOV AX,2000
-t
AX=2000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=139A ES=139A SS=139A CS=139A IP=0103 NV UP EI PL NZ NA PO NC
139A:0103 8EC0 MOV ES,AX
-t
AX=2000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=139A ES=2000 SS=139A CS=139A IP=0105 NV UP EI PL NZ NA PO NC
139A:0105 26 ES:
139A:0106 FF2E0010 JMP FAR [1000] ES:1000=00BE
-t
AX=2000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=139A ES=2000 SS=139A CS=0006 IP=00BE NV UP EI PL NZ NA PO NC
0006:00BE 00F0 ADD AL,DH
-
|
|