. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->CALL和RET指令
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  第10章汇编课题:多方位,多角度,综合超级无敌研究大总结~  [待解决] 回复[ 1次 ]   点击[ 422次 ]  
110_112
[帖 主]   [ 发表时间:2010-04-13 01:39 ]   [引用]   [回复]   [ top ] 
荣誉值:6
信誉值:0
注册日期:2010-03-17 10:10
看王爽的汇编语言也不短了。当读到第10章很显然感觉到了点吃力,虽然讲解的很清晰,可是一些检测点的问题还是有些不明白的地方。现在我决定留级重新温习下第10章,并全部重新做一遍习题,并分析它。咱是小白,那就以小白的眼光看题目啦,大家可以进来瞧瞧。

第10章  CALL和RET指令
```````````````````````````````````````````````````````````````````````````````````````` 10.1  ret 和retf

检测点10.1
补全程序,实现从内存1000:0000处开始执行的指令

assume cs:code

stack segment
db 16 dup(0)
stack ends

code segment

start:mov ax,stack     
      mov ss,ax   ---------将标记stack段地址传送给ss.
      mov sp,16   ---------Sp标记堆栈顶部.

      mov ax,_____   ------这里开始就是这个题目的关键了,现在看到这个题目感觉上,没原先那么难
      push ax        ------了,关键是不熟悉,不熟练啊。让我再预习下retf的机制。
      mov ax,_____   ------首先出榨:pop ip 然后出榨pop cs,这个顺序要记牢,要熟练,我就是吃了
                        ------这个的亏啊。先出ip就必须先进cs,这样才行。

      retf           -----记好了顺序,然后我们从题目了解到,cs:1000,ip,0现在只要套进去就可以  
      code ends      -----乐,就像我上面说的那样先出ip就必须先进cs,这是堆栈的机制。所以答案就是
      end start      ---------1000,,,0,,,,



总结:没别的理由,问题很简单,就是熟练,上手很差,总是会想错地方。有句话说的好,一听都会,一做就错。 还是要多做题,多帮人啊。

``````````````````````````````````````````````````````````````````````````````````````````
10.2  call指令

检测点10.2

下面的程序执行后,ax的数值是多少?

内存地址     机器码   汇编指令
1000:0             mov ax,0     -----指令缓存器赋值给段寄存器数值0
1000:3     省略     call s       -----call机制,push ip  然后位移位到标号处也就是地址1000:7
1000:6             inc ax       -----将现有Ip:6压榨起来,此步将不进行.
1000:7             s:pop ax     -----提取压榨出的6赋值给ax,后sp+2程序结束,正确答案为6

总结,哇塞竟然对了,我绝的我第一次死都想不明白的。哎,或许当时心里杂念太多了。果然自己一步一步做过来,还是可以对的啊。大家也可以学我一样把自己做的题目写出来和大家分享。即使好多人都写出来了一样的东西又能如何呢,这可是提高自己的学习的一个好方法啊。

```````````````````````````````````````````````````````````````````````````````````````````

检测点10.3
下面的程序执行后,ax的数值为多少?

内存地址      机器码    汇编指令
1000:0       省      mov ax,0         --------无
1000:3       略      call far ptr s   ---远地址转移call 将要push cs,push ip 然后跳转到标号处
1000:8       -      inc ax
1000:9       -      s:pop ax         --- 出栈也就是将最后压榨的ip提出此时ax为8
                     add ax,ax        ---8H+8H=10H .ax:10
                     pop bx          --- 继续出栈,现在是该cs了cs出来后,bx为1000
                     add ax,bx       ---继续相加,哦也,又答对了,1010

总结,没啥说的,俺是一级棒。O(∩_∩)O哈哈~,真没想到再次做题,竟然一直答对。果然我也是不赖的。

`````````````````````````````````````````````````````````````````````````````````````````
检测点 10.4

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

内存地址     机器码    汇编指令
1000:0      省      mov ax,6   
1000:2      略      call ax        ----- 老规矩,压榨啊压榨,压榨ip:5然后跳转到位移为6的地方
1000:5      ·      inc ax
1000:6      ·      mov bp,sp       ---- 将堆栈顶端地址赋值给bp
                    add ax,[bp]    ---  地址数值与ax相加,也就是(ax)=(ax)+(Ip) 答案为B
                                  ----ax的数值为000B。

总结:答案在我看第一遍的时候我就开过来,可是当时我就是不晓得为什么我不晓得理由,不过再做一遍,算到B的时候,我笑了。难道天才就是这样炼成的。

```````````````````````````````````````````````````````````````````````````````````````````````

检测题 10.5

(1)下面的程序执行后,ax中的数值时多少?(注意:用call指令的原理分析,不要再debug中单步跟踪,来验证你的结论,对于此程序,在Debug中,单步跟踪的结果,不能代表CPU实际工作情况)

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                       --把段寄存器DS也指向SS
      mov ax,0                        
      call word ptr ds:[0EH]          --压榨IP。从DS:[03h]中,提取跳转的Ip
      inc ax                   ↑我把堆栈段的内容写出来就一目了然了。
      inc ax                  dw,0,0,0,0,0,0,0,IP,
      inc ax                  ↑提出来的和存进去的是一个位子。所以ax为3
      mov ax,4C00H
      int 21H
code ends
end start

总结,不败神话总算结束了,我做这题很ORZ,拜托,不要忽然出现不需要压榨段地址的啊。是用ip定位转移目标的。
在我脑子里,一共记得3种转移的种类,1通过位移转移,2通过CS和ip转移,3只需要通过ip转移,这些需要以后的实践中多多应用,就会了解很多了,我相信大家也有很多人会一时间分不清的。以上纯属个人意见,错误当然漫天飞了,希望朋友指正。

(2)下面的程序执行后,AX和BX中的数值是多少?
assume cs:code
data segment
dw 8 dup(0)
data ends
code segment
start:mov ax,data
      mov ss,ax
      mov sp,16                ------堆栈确认,供下使用
      mov word ptr ss:[0],offset s  ----标记的偏移地址存入堆栈底部
      mov ss:[2],cs                 ----CS存入到SS+2中
      call dword ptr ss:[0]         -----压缩CS,IP,拿出楼上刚刚存的IP,CS。跳转到S上。
      nop                           ----nop不知为何用,不过查了查,此指令常用于程序的延迟占用
                                         -----1字节哦
      s:mov ax,offset s             
      sub ax,ss:[0cH]               ----下面的大家认真看吧,看的我头晕了。
      mov bx,cs                     -----说不太清楚,反正就是不同的Ip相减,剩下了1.因为一个是
      sub bx,ss:[0eh]              ---语句nop上面的地址,一个是下面的相差1字节。
      mov ax,4c00h                 -----另一个是相同的CS相减,得出了0.我这里的Ip和CS大家可以
      int 21h                      ----理解成曾经的与现在的。
code ends                          ----正确答案是AX:1 BX:0
end start

总结:这题目第一次做对的很强了,我是这么认为的,因为我是看了答案的。哈哈。



今天很晚了,明天继续努力学习汇编喽。大家晚安~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~夜晚1:43的问候。
versaariel
[第1楼]   [ 回复时间:2010-04-13 09:09 ]   [引用]   [回复]   [ top ] 
荣誉值:62
信誉值:0
注册日期:2009-12-03 13:14
挺好的^-^,认真看书,多上DEBUG实验
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved