首页
社区
课程
招聘
汇编call指令疑问,期待高手解答
发表于: 2010-10-14 00:38 8131

汇编call指令疑问,期待高手解答

2010-10-14 00:38
8131
本人最近在学习汇编语言时,在call指令的理解上存有疑惑,期待各位高手不吝指教!

题目:下面的程序执行后,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

个人一直认为执行call指令后,直接跳转到ds:[0eh]处执行命令,就不在执行下面的几条指令了~
期待高手的详细解答~非常感谢!

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (12)
雪    币: 247
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
首先你的理解就有误,CALL俗称子程序调用,如果学过C语言的话,CALL相当于调用一个函数。函数调用最终是要返回的,也就是执行完
call word ptr ds:[0EH]
ds:[0EH]子程序后返回继续执行
inc ax

引用“个人一直认为执行call指令后,直接跳转到ds:[0eh]处执行命令,就不在执行下面的几条指令了~”
这句应该是JMP的功能,但是也要看具体情况,假设你的ds:[0eh]指向的位置就是下一条指令,那也不会跳过下面的几条指令
2010-10-14 02:24
0
雪    币: 188
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
非常感谢您的回答,那我想问一下,针对这个程序call指令如何返回呢??因为这个程序中
ds:[0Eh]地址后的程序是不确定的!
我想知道是不是call指令不论执行什么程序,最终都会返回原程序执行后续内容。
感谢~
2010-10-14 07:50
0
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
call指令执行时,进行两步操作:
一,将当前的IP或者CS和IP压入堆栈中。
二,转移。
2010-10-14 08:10
0
雪    币: 468
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
你的call ds:[0eh]是先取出ds:[0eh]处的地址,而ds根据前面的mov ds,ax赋值,表示ds等于堆栈段SS等于stack。而根据你的堆栈段定义只有16个字节,因此ds:[0eh]就是栈顶的值,而执行call ds:[0eh]的时候,机器的操作是先把返回地址压入栈顶,就是返回call ds:[0eh]的下一条指令,即inc eax这条指令的地址压入栈顶,所以实际上执行call ds:[0eh]以后,就直接跳转到下一条指令,执行inc eax了。连着3个inc eax,如果要问这个时候的ax的值,ax=stack+3,然后又mov ax,4c00h,显然ax=4c00h了,下条指令结束程序,即,ax=4c00h,int 21h    dos程序的结素功能。
2010-10-14 08:57
0
雪    币: 36
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
同意楼上,结果AX=0X4C00,调用中断时需要给AH赋值.实际这段程序等价于
MOV AH,4C
INT 21
即安全退出程序
2010-10-14 10:28
0
雪    币: 245
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
上面的都分析了 call指令执行时,进行两步操作:
一,将当前的IP或者CS和IP压入堆栈中。
二,转移到调用的子程序。

执行call ds:[0eh]的时候:
第一,机器的操作是先把返回地址压入栈顶,就是返回call ds:[0eh]的下一条指令,即inc ax这条指令的地址压入栈顶
第二,开始执行子程序,即ds:[0eh]处的指令,而ds:[0eh]就是堆栈栈顶的值,而堆栈栈顶的值就是第一步中inc ax这条指令的地址,所以跳转到CS:ip处开始执行,也就
是inc ax这条指令。
2010-10-14 11:28
0
雪    币: 247
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
[QUOTE=alllife;871539]非常感谢您的回答,那我想问一下,针对这个程序call指令如何返回呢??因为这个程序中
ds:[0Eh]地址后的程序是不确定的!
我想知道是不是call指令不论执行什么程序,最终都会返回原程序执行后续内容。
感谢~[/QUOTE]

CALL指令执行后,会将当前的IP或者CS和IP  指令的地址压入堆栈,然后执行子程序。在否最终回到原程序执行后续内容,这个也要看调用的子程序最终是否返回,不是CALL能决定的。
返回的指令是ret,retf,即当子程序中无死循环,且call和ret配对使用时,才能返回。

一般使用方法如下。

     call  s             ;调用s子程序
        mov ax,4c00h
        int 21h

     s:inc ax
        ret

call 将ip入栈,ret将ip出栈

0EH这个地址不确定,这个说法是不对的

是可以计算出来的,比如用DEBUG反汇编你的这个程序,可以看到DS:[0EH]指向的位置,WINHEX也应该是可以的,说的不对的地方见谅,我也才学不久,共勉。
2010-10-14 11:48
0
雪    币: 247
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
显然ds  ss 是同一段,栈顶指针在16也就是10h,压入ip(第一条inc ax的指令的地址,16位偏移地址)后,(sp)-2 = 0eh,而此时要转去以ds:[0eh]单元内容为地址的地方执行,这个地址恰恰是第一条inc ax的指令的地址((ds)=(ss),(sp)=0eh),所以当call word ptr ds:[0eh] 指令执行后cpu 将继续向下执行call word ptr ds:[0eh]的下一条指令
之前(ax) = 0 三个inc ax 后 等于3
参考:http://www.asmedu.net/bbs/pasteinfo.jsp?part=1&level=book&kind=1011&qID=1112
2010-10-14 13:52
0
雪    币: 188
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
非常感谢各位的回答,感觉受益匪浅!本人也是刚学,与各位共同学习提高!
2010-10-15 11:01
0
雪    币: 188
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
想问一下,最后那个退出指令 mov ax,4c00h!是否对ax进行赋值操作?就是说执行程序后ax=3还是4c00h感谢!
2010-10-15 11:03
0
雪    币: 247
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
当然是最后赋值的操作了
用高级语言描述应该是这样的
ax++;
ax++;
ax++;
ax=4c00h;
2010-10-15 11:10
0
雪    币: 468
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
楼主不地道,有问题我都懒回答了,ax从来没有等于3,不给分???·!#¥·#¥
2010-10-15 16:42
0
游客
登录 | 注册 方可回帖
返回
//