王爽汇编语言检测点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:[0eh] ;
inc ax
inc ax
inc ax
mov ax,4c00h
int 21h
code ends
end start
答案:ax=3
分析:
1、本题stack段用 dw 8 dup (0)定义了16字节内存为0的栈段,所以ds:[0]~ds:[f]的内存单元全部为0,当然,ds:[0E]单元的内存自然就为0了!
2、本题ds=ss,也即数据段与栈段于同一段内,sp=16,指向栈顶,当指令执行到call word ptr ds:[0eh]这条指令的时候,相当于进行了:(1)PUSH IP(此时IP的值为CALL语句下一条语句的偏移地址,也就是INC AX的偏移地址),由于初始栈顶指针指向16,所以push ip执行时,选将指针进行了ip=ip-2的操作,使ip指向14,也就是0eh,再将call word ptr ds:[0eh]的下一条指令INC AX的偏移地址入栈到oeh处 ;(2)JMP WORD PTR SS(因为DS等于SS):[0EH],此时程序跳转到CS:SS:[OEH]处执行,因为 SS:[0EH]的值为0,所以跳转到CS:0处开始执行,也就是程序的第一条语句MOV AX;(3)当程序再一次执行到call word ptr ds:[0EH]时,指针将跳转到ds:[0eh] ,而此时的:[0eh]处的值已经不是0了,它已变成上次执行call时被压栈的INC AX处的移地址,它使执行call word ptr ds:[0eh]的跳转直接跳到指令inc,ax处,连续3次inc 后,AX的值为3.
其实,检测点10.5(2)与此题一致,无非是压栈时多压入了一个cs的值!
本篇博文 装载于梨苑深深的博客
本人自己用debug单步执行时 遇到了如下问题
AX=141E BX=0000 CX=0029 DX=0000 SP=0010 BP=0000 SI=0000 DI=0000
DS=141E ES=140E SS=141E CS=141F IP=000A NV UP EI PL NZ NA PO NC
141F:000A B80000 MOV AX,0000
-t
AX=0000 BX=0000 CX=0029 DX=0000 SP=0010 BP=0000 SI=0000 DI=0000
DS=141E ES=140E SS=141E CS=141F IP=000D NV UP EI PL NZ NA PO NC
141F:000D FF160E00 CALL [000E] DS:000E=
-t
AX=0000 BX=0000 CX=0029 DX=0000 SP=000E BP=0000 SI=0000 DI=0000
DS=141E ES=140E SS=141E CS=141F IP=3302 NV UP EI PL NZ NA PO NC
141F:3302 26 ES:
141F:3303 0BC0 OR AX,AX
即执行call语句之后 ip竟然被改成3302了 这意思是ds:[0eh]总的内容是3302喽?
带着这个疑问又 重新从头来了一遍
141F:0003 8ED0 MOV SS,AX
-d 141e:00
141E:0000 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
141E:0010 B8 1E 14 8E D0 BC 10 00-8E D8 B8 00 00 FF 16 0E ................
141E:0020 00 40 40 40 B8 00 4C CD-21 09 5F 83 C4 04 FF 76 .@@@..L.!._....v
141E:0030 04 FF 36 24 21 E8 BC 44-83 C4 04 80 3E 60 08 00 ..6$!..D....>`..
141E:0040 74 3A 8B 9E 72 FF 8B 36-D2 25 8A 00 88 86 70 FF t:..r..6.%....p.
141E:0050 0A C0 74 28 C4 5E 06 26-83 7F 06 00 74 1E A1 A4 ..t(.^.&....t...
141E:0060 07 39 86 72 FF 77 15 8A-86 70 FF 2A E4 50 B8 FD .9.r.w...p.*.P..
141E:0070 05 50 FF 36 24 21 E8 77-63 83 C4 06 FF 36 24 21 .P.6$!.wc....6$!
-t
AX=141E BX=0000 CX=0029 DX=0000 SP=0010 BP=0000 SI=0000 DI=0000
DS=140E ES=140E SS=141E CS=141F IP=0008 NV UP EI PL NZ NA PO NC
141F:0008 8ED8 MOV DS,AX
-d 141e:00
141E:0000 00 00 00 00 00 00 1E 14-00 00 08 00 1F 14 0F 0E ................
141E:0010 B8 1E 14 8E D0 BC 10 00-8E D8 B8 00 00 FF 16 0E ................
141E:0020 00 40 40 40 B8 00 4C CD-21 09 5F 83 C4 04 FF 76 .@@@..L.!._....v
141E:0030 04 FF 36 24 21 E8 BC 44-83 C4 04 80 3E 60 08 00 ..6$!..D....>`..
141E:0040 74 3A 8B 9E 72 FF 8B 36-D2 25 8A 00 88 86 70 FF t:..r..6.%....p.
141E:0050 0A C0 74 28 C4 5E 06 26-83 7F 06 00 74 1E A1 A4 ..t(.^.&....t...
141E:0060 07 39 86 72 FF 77 15 8A-86 70 FF 2A E4 50 B8 FD .9.r.w...p.*.P..
141E:0070 05 50 FF 36 24 21 E8 77-63 83 C4 06 FF 36 24 21 .P.6$!.wc....6$!
-
这意味着 运行完 mov ds,ax后141e:00到141e:0010内容改变了 彻底凌乱
更加凌乱的是
-t
AX=0000 BX=0000 CX=0029 DX=0000 SP=0010 BP=0000 SI=0000 DI=0000
DS=141E ES=140E SS=141E CS=141F IP=000D NV UP EI PL NZ NA PO NC
141F:000D FF160E00 CALL [000E] DS:000E=0E0F
-d 141e:00
141E:0000 00 00 00 00 00 00 00 00-00 00 0D 00 1F 14 0F 0E ................
141E:0010 B8 1E 14 8E D0 BC 10 00-8E D8 B8 00 00 FF 16 0E ................
141E:0020 00 40 40 40 B8 00 4C CD-21 09 5F 83 C4 04 FF 76 .@@@..L.!._....v
141E:0030 04 FF 36 24 21 E8 BC 44-83 C4 04 80 3E 60 08 00 ..6$!..D....>`..
141E:0040 74 3A 8B 9E 72 FF 8B 36-D2 25 8A 00 88 86 70 FF t:..r..6.%....p.
141E:0050 0A C0 74 28 C4 5E 06 26-83 7F 06 00 74 1E A1 A4 ..t(.^.&....t...
141E:0060 07 39 86 72 FF 77 15 8A-86 70 FF 2A E4 50 B8 FD .9.r.w...p.*.P..
141E:0070 05 50 FF 36 24 21 E8 77-63 83 C4 06 FF 36 24 21 .P.6$!.wc....6$!
-t
AX=0000 BX=0000 CX=0029 DX=0000 SP=000E BP=0000 SI=0000 DI=0000
DS=141E ES=140E SS=141E CS=141F IP=3302 NV UP EI PL NZ NA PO NC
141F:3302 26 ES:
141F:3303 0BC0 OR AX,AX
-
在call运行之前 ds:[0eh]中存有的根本不是0000 连3302都不是 这是要闹哪样? 彻底凌乱
-