鱼C论坛

 找回密码
 立即注册
查看: 3465|回复: 1

王爽测试10.5 问题

[复制链接]
发表于 2016-7-22 10:36:13 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. assume cs:code
  2. stack segment
  3.         dw 8 dup (0)
  4. stack ends

  5. code segment
  6.         start:mov ax,stack
  7.                   mov ss,ax
  8.                   mov sp,16
  9.                   mov ds,ax
  10.                   mov ax,0
  11.                   
  12.                   call word ptr ds:[0EH]
  13.                   inc ax
  14.                   inc ax
  15.                   inc ax
  16.                   
  17.                   mov ax,4c00h
  18.                   int 21h
  19.         code ends
  20. end start
  21. ;答案:ax=3
  22. ;分析:
  23. ;1、本题stack段用 dw 8 dup (0)定义了16字节内存为0的栈段,所以ds:[0]~ds:[f]的内存单元全部为0,当然,ds:[0E]单元的内存自然就为0了!
  24. ;2、本题ds=ss,也即数据段与栈段于同一段内,sp=16,指向栈顶,当指令执行到call word ptr ds:[0eh]这条指令的时候,相当于进行了:

  25. ;(1)PUSH IP(此时IP的值为CALL语句下一条语句的偏移地址,也就是INC AX的偏移地址),由于初始栈顶指针指向16,所以push ip执行时,选将指针进行了ip=ip-2的操作,使ip指向14,也就是0eh,再将call word ptr ds:[0eh]的下一条指令INC AX的偏移地址入栈到oeh处 ;
  26. ;(2)JMP WORD PTR SS(因为DS等于SS):[0EH],此时程序跳转到CS:(SS:[OEH])处执行,因为 SS:[0EH]的值为0,所以跳转到CS:0处开始执行,也就是程序的第一条语句MOV AX;
  27. ;(3)当程序再一次执行到call word ptr ds:[0EH]时,指针将跳转到ds:[0eh] ,而此时的:[0eh]处的值已经不是0了,它已变成上次执行call时被压栈的INC AX处的移地址,它使执行call word ptr ds:[0eh]的跳转直接跳到指令inc,ax处,连续3次inc 后,AX的值为3.
复制代码



下面的答案是网上找的
第一步是说  在ds:[0eh] 处存储了call 的以一条指令的地址
第二步为啥说 ds:[0eh] 为 0 ,不应该啊?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2016-7-22 17:10:37 | 显示全部楼层
"第一步是说  在ds:[0eh] 处存储了call 的一条指令的地址"
怎么理解,你那里不明白吗?

一开始 ds:[0eh] 的确是0
执行完 call word ptr ds:[0EH] 后改变成了call word ptr ds:[0EH]下一条指令的偏移地址 (是执行完以后改变的)

我亲自调试过,上面的分析是正确的

这是我的调试过程,可能会帮到你
  1. (0) context not implemented because BX_HAVE_HASH_MAP=0
  2. [0x000ffff0] f000:fff0 (unk. ctxt): jmp f000:e05b             ; ea5be000f0
  3. <bochs:1> b 0x 7c00
  4. ..\bochsdbg.exe:1: syntax error at 'x'
  5. <bochs:2> b 0x7c00
  6. <bochs:3> c
  7. (0) Breakpoint 1, 0x7c00 in ?? ()
  8. Next at t=2393208
  9. (0) [0x00007c00] 0000:7c00 (unk. ctxt): mov ax, 0x7c0             ; b8c007
  10. <bochs:4> set $ip=0
  11. Error: set: unrecognized symbol.
  12. <bochs:5> info reg
  13. eax            0xaa55           43605
  14. ecx            0x100001         1048577
  15. edx            0x80             128
  16. ebx            0x80             128
  17. esp            0xfffe           0xfffe
  18. ebp            0x0              0x0
  19. esi            0x0              0
  20. edi            0xffe4           65508
  21. eip            0x7c00           0x7c00
  22. eflags         0x282            642
  23. cs             0x0              0
  24. ss             0x0              0
  25. ds             0x0              0
  26. es             0x0              0
  27. fs             0x0              0
  28. gs             0x0              0
  29. <bochs:6> set $eip=0
  30. <bochs:7> set $cs=0x7c0
  31. <bochs:8> s
  32. Next at t=2393209
  33. (0) [0x00007c03] 07c0:0003 (unk. ctxt): mov ss, ax                ; 8ed0
  34. <bochs:9>
  35. Next at t=2393210
  36. (0) [0x00007c05] 07c0:0005 (unk. ctxt): mov sp, 0x25              ; bc2500
  37. <bochs:10>
  38. Next at t=2393211
  39. (0) [0x00007c08] 07c0:0008 (unk. ctxt): mov ds, ax                ; 8ed8
  40. <bochs:11>
  41. Next at t=2393212
  42. (0) [0x00007c0a] 07c0:000a (unk. ctxt): mov ax, 0x0               ; b80000
  43. <bochs:12>
  44. Next at t=2393213
  45. [color=Red](0) [0x00007c0d] 07c0:000d (unk. ctxt): ds call word ptr [ds:0x23] ; 3eff162300[/color] // 第一次执行
  46. <bochs:13>
  47. Next at t=2393214
  48. [color=Red](0) [0x00007c00] 07c0:0000 (unk. ctxt): mov ax, 0x7c0             ; b8c007[/color] // 这里执行回到一开始的  mov ax, 0x7c0             ; b8c007
  49. <bochs:14>
  50. Next at t=2393215
  51. (0) [0x00007c03] 07c0:0003 (unk. ctxt): mov ss, ax                ; 8ed0
  52. <bochs:15>
  53. Next at t=2393216
  54. (0) [0x00007c05] 07c0:0005 (unk. ctxt): mov sp, 0x25              ; bc2500
  55. <bochs:16>
  56. Next at t=2393217
  57. (0) [0x00007c08] 07c0:0008 (unk. ctxt): mov ds, ax                ; 8ed8
  58. <bochs:17>
  59. Next at t=2393218
  60. (0) [0x00007c0a] 07c0:000a (unk. ctxt): mov ax, 0x0               ; b80000
  61. <bochs:18>
  62. Next at t=2393219
  63. [color=Red](0) [0x00007c0d] 07c0:000d (unk. ctxt): ds call word ptr [ds:0x23] ; 3eff162300[/color] //第二次执行
  64. <bochs:19>
  65. Next at t=2393220
  66. [color=Red](0) [0x00007c12] 07c0:0012 (unk. ctxt): inc ax                    ; 40[/color] //因为第一次执行 call word ptr [ds:0x23] 时,堆栈段偏移 0x23 的值已经是这条指令的地址
  67. <bochs:20>
  68. Next at t=2393221
  69. (0) [0x00007c13] 07c0:0013 (unk. ctxt): inc ax                    ; 40
  70. <bochs:21>
  71. Next at t=2393222
  72. (0) [0x00007c14] 07c0:0014 (unk. ctxt): inc ax                    ; 40
  73. <bochs:22>
  74. Next at t=2393223
  75. (0) [0x00007c15] 07c0:0015 (unk. ctxt): add byte ptr ds:[bx+si], al ; 0000
  76. <bochs:23>

复制代码


这是我用bochs调试的
这是程序源码
  1.         mov ax,0x07c0
  2.         mov ss,ax
  3.         mov sp,stack + 16
  4.         mov ds,ax
  5.         mov ax,0

  6.         call word [ds:23H]

  7.         inc ax
  8.         inc ax
  9.         inc ax

  10. stack:       
  11.         resb 16

  12.          times 510-($-$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为   
  13.         dw 0xaa55 ; 结束标志  
复制代码

你如果要自己调试,请修改cs,eip的值(没错,是eip,bochs没有ip寄存器)
cs修改为 0x7c0
eip修改为 0
具体方法看我调试过程
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-6 09:14

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表