丶Haw 发表于 2012-8-1 01:37:16

10.5(2)求解

assume cs:codesgstack segment    dw 8 dup(0)stack endscodesg segmentstart:    mov ax,stack    mov ss,ax    mov sp,10h    mov word ptr ss:,offset s ;(ss:)=1ah    mov ss:,cs                ;(ss:)=cs    call dword ptr ss:      ;cs入栈,ip=19h入栈,转到cs:1ah处执行指令                                 ;(ss:)=cs,(ss:)=ip有些答案上说这里是=cs=ip?到底哪个才是对的!    nops:mov ax,offset s            ;ax=1ah    sub ax,ss:             ;ax=1ah-(ss:)=1ah-19h=1   这里为什么【0ch】=19h?    mov bx,cs                   ;bx=cs=0c5bh                   sub bx,ss:            ;bx=cs-cs=0               ss:=cs?why?    mov ax,4c00h    int 21hcodesg endsend start

lukelqz 发表于 2012-8-1 01:37:17

你如果把10.4我给你解释的弄懂了。这题问题不大,关键就是你要弄懂栈和call。给你看下我的debug图。

看到了把,call后面的指令的第一个字节的ip为0019h,这是什么决定的呢?就是从程序的入口到执行到call的总共占用的机器码决定的,这题总共占了19个字节。所以就这样了。

注意这里是call dword ptr 内存单元地址哦。相当于:
push cs
push ip
jmp dword ptr 内存单元地址

这题关键就是这条命令
call dword ptr ss:执行完了后,栈中的情况是什么样的呢。注意开始题目中给出了栈段和sp。要注意利用。


注意栈是以字为单位的,就是2个字节。这样先把cs入栈占用两个字节,sp自减2,sp=0eh。这时候ss:0eh字单元里面存放的是cs的内容,比如我的debug图中就是0b67h。然后再把ip入栈,sp自减2,sp=0ch,这时候ss:0ch字单元里面存放的是ip的内容,这个ip是call指令后的第一个字节的ip,我的debug图中是0019h。

入栈结束,就可以jmp dword ptr ss:了。其实也就是跳到s标号处执行,因为执行了这步
mov word ptr ss:,offset s
你的问题应该能解决了吧。我感觉我好啰嗦啊。{:5_100:}不懂再回吧。

lukelqz 发表于 2012-8-1 12:32:06

你把上面的弄明白了,就去看看这个帅哥的帖子http://bbs.fishc.com/thread-19409-1-1.html。其实就是利用了call的用法,以及nop占一个字节

丶Haw 发表于 2012-8-1 12:52:11

lukelqz 发表于 2012-8-1 01:37 static/image/common/back.gif
你如果把10.4我给你解释的弄懂了。这题问题不大,关键就是你要弄懂栈和call。给你看下我的debug图。

看到 ...

非常感谢 ,你用的是什么编辑器?

lukelqz 发表于 2012-8-1 12:58:08

丶Haw 发表于 2012-8-1 12:52 static/image/common/back.gif
非常感谢 ,你用的是什么编辑器?

notepad++{:5_93:}

丶Haw 发表于 2012-8-3 22:03:27

lukelqz 发表于 2012-8-1 12:58 static/image/common/back.gif
notepad++

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:

   inc ax

   inc ax

   inc ax

   mov ax,4c00h

   int 21h

code ends

end start

u指令查看是

0C50:0000 B84F0C      MOV   AX,0C4F

0C50:0003 8ED0          MOV   SS,AX

0C50:0005 BC1000      MOV   SP,0010

0C50:0008 8ED8          MOV   DS,AX

0C50:000A B80000      MOV   AX,0000

0C50:000D FF160E00      CALL   

0C50:0011 40            INC   AX

0C50:0012 40            INC   AX

0C50:0013 40            INC   AX

0C50:0014 B8004C      MOV   AX,4C00

0C50:0017 CD21          INT   21

这个题目,用debug 后,
call
下面怎么跑到别的地方去了!而没有运行下面的程序,这是为什么?求解!

丶Haw 发表于 2012-8-3 22:03:59

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:

   inc ax

   inc ax

   inc ax

   mov ax,4c00h

   int 21h

code ends

end start

u指令查看是

0C50:0000 B84F0C      MOV   AX,0C4F

0C50:0003 8ED0          MOV   SS,AX

0C50:0005 BC1000      MOV   SP,0010

0C50:0008 8ED8          MOV   DS,AX

0C50:000A B80000      MOV   AX,0000

0C50:000D FF160E00      CALL   

0C50:0011 40            INC   AX

0C50:0012 40            INC   AX

0C50:0013 40            INC   AX

0C50:0014 B8004C      MOV   AX,4C00

0C50:0017 CD21          INT   21

这个题目,用debug 后,
call
下面怎么跑到别的地方去了!而没有运行下面的程序,这是为什么?求解!

丶Haw 发表于 2012-8-3 22:05:19

检测点10.5

(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 ds,ax

   mov ax,0

   call word ptr ds:

   inc ax

   inc ax

   inc ax

   mov ax,4c00h

   int 21h

code ends

end start



推算:

执行call word ptr ds:指令时,先cs入栈,再ip=11入栈,最后ip转移到(ds:)。(ds:)=11h,执行inc ax……最终ax=3



题中特别关照别用debug跟踪,跟踪结果不一定正确,但还是忍不住去试试,看是什么结果。

根据单步跟踪发现,执行call word ptr ds:指令时,显示ds:=065D。

ds:0000~ds:0010不是已设置成stack数据段了嘛,不是应该全都是0的嘛。

于是进行了更详细的单步跟踪,发现初始数据段中数据确实为0,但执行完mov ss,ax;mov sp,16这两条指令后,数据段中数据发生改变。这是为什么呢?



C:\DOCUME~1\SNUSER>debug jc10-5.exe

-u

0C50:0000 B84F0C      MOV   AX,0C4F

0C50:0003 8ED0          MOV   SS,AX

0C50:0005 BC1000      MOV   SP,0010

0C50:0008 8ED8          MOV   DS,AX

0C50:000A B80000      MOV   AX,0000

0C50:000D FF160E00      CALL   

0C50:0011 40            INC   AX

0C50:0012 40            INC   AX

0C50:0013 40            INC   AX

0C50:0014 B8004C      MOV   AX,4C00

0C50:0017 CD21          INT   21

-r

AX=0000BX=0000CX=0029DX=0000SP=0000BP=0000SI=0000DI=0000

DS=0C3FES=0C3FSS=0C4FCS=0C50IP=0000   NV UP EI PL NZ NA PO NC

0C50:0000 B84F0C      MOV   AX,0C4F

-d 0c4f:0 f

0C4F:000000 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................

-t

AX=0C4FBX=0000CX=0029DX=0000SP=0000BP=0000SI=0000DI=0000

DS=0C3FES=0C3FSS=0C4FCS=0C50IP=0003   NV UP EI PL NZ NA PO NC

0C50:0003 8ED0          MOV   SS,AX

-d 0c4f:0 f

0C4F:000000 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................

-t

AX=0C4FBX=0000CX=0029DX=0000SP=0010BP=0000SI=0000DI=0000

DS=0C3FES=0C3FSS=0C4FCS=0C50IP=0008   NV UP EI PL NZ NA PO NC

0C50:0008 8ED8          MOV   DS,AX

-d 0c4f:0 f

0C4F:000000 00 00 00 00 00 4F 0C-00 00 08 00 50 0C 5D 06   ......O.....P.].

-t

AX=0C4FBX=0000CX=0029DX=0000SP=0010BP=0000SI=0000DI=0000

DS=0C4FES=0C3FSS=0C4FCS=0C50IP=000A   NV UP EI PL NZ NA PO NC

0C50:000A B80000      MOV   AX,0000

-d 0c4f:0 f

0C4F:000000 00 00 00 00 00 4F 0C-00 00 0A 00 50 0C 5D 06   ......O.....P.].

-t

AX=0000BX=0000CX=0029DX=0000SP=0010BP=0000SI=0000DI=0000

DS=0C4FES=0C3FSS=0C4FCS=0C50IP=000D   NV UP EI PL NZ NA PO NC

0C50:000D FF160E00      CALL                               DS:000E=065D

-d 0c4f:0 f

0C4F:000000 00 00 00 00 00 00 00-00 00 0D 00 50 0C 5D 06   ............P.].

lukelqz 发表于 2012-8-3 22:43:54

丶Haw 发表于 2012-8-3 22:05 static/image/common/back.gif
检测点10.5

(1)下面的程序执行后,ax中的数值为多少?


这题关键在于不能用t命令单步调试。因为ds段和ss段重合了,所以理论上call入栈后,ds:=ss:=ip=11h。
但是如果用t命令单步调试会产生中断,并且会向ss段压入临时的值,这时候ds:就不等于11h了。
用g命令直接跳过就没事了。


以后学中断应该就知道了。
参考阅读:http://blog.csdn.net/wankong/article/details/1322703
页: [1]
查看完整版本: 10.5(2)求解