汇编Call指令问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了汇编Call指令问题相关的知识,希望对你有一定的参考价值。

执行callfar ptr s后 cs=1000 ip=3(10H)接着进栈 然后执行pop ax 此时ax=3
==〉add ax,ax此时ax=6(100H)==〉pop bx 此时bx=1000 ==〉add ax,bx此时ax=1100H

答案那里 3怎么会是10H啊 ?
6=10H ?
怎么理解啊 ?

执行长调用 CALL,压入堆栈的内容,是其下条指令的地址:1000:0008。

在子程序中,

pop ax ,将有:AX = 0008。

ADD 后,即有:AX = 0010。

POP BX,将有:BX = 1000。

ADD AX, BX,结果就是 AX = 1010H。
参考技术A call far会先压段地址,再压入入下一条指令的IP到栈中,

因此后面的 pop ax 将inc ax的地址弹出[上面为3]

pop bx会获得执行CALL之前的段地址[上面为1000]

3*2+1000=1006h

PS:6=110b = 6h ≠ 110h追问

那就是参考答案错咯 ?

参考技术B

    你看书都没看call的ip指向!

    书上说了用call far ptr X 时 

    先把cs入栈,此时cs=1000h,

    然后入栈的是call指令的下一条指令地址,下一条,下一条,下一条,多说几句看你是否记得!

    【你要搞清楚不是call自身的那条指令的地址,你想call死自己啊】

    也就是inc ax的地址1000:8→ip=0008h,而非call far ptr s的偏移地址!

    跟着最后进栈的先出,ip=0008h是后进的栈,要先出,pop ax就是把0008h传送给ax,

    此时ax=8,add ax,ax 就是8+8=16,16的十六进制就是10H;

    再把先进的弹出栈pop bx先进栈的是cs=1000h→就把1000h弹给bx,

    此时ax=10h,bx=1000h → ax+bx → 10h+1000h=1010h,

    OK

汇编语言——call 和 ret 指令

 

一、ret 和 retf

我们用汇编语法来解释ret和retf指令,则:

CPU执行ret指令时,相当于进行:

  • pop IP

CPU执行retf指令时,相当于进行:

  • pop IP(一般IP都是在低位地址的)
  • pop CS(CS在高位地址)

二、call指令

CPU执行call指令,进行两步操作:

(1)将当前的 IP 或 CS和IP 压入栈中;

(2)转移。

call 指令不能实现段内短转移,除此之外,call指令实现转移的方法和 jmp 指令的原理相同,下面的几个小节中 ,我们以给出转移目的地址的不同方法为主线,讲解call指令的主要应用格式。

段内转移

指令格式:call 标号

CPU执行上面指令相当于进行:

push IP

jmp near ptr 标号

段间转移

指令格式:call far ptr 标号

CPU 执行上面指令时,相当于进行:

push CS

push IP

jmp far ptr 标号

转移地址在寄存器中的call指令

指令样式:call 16位寄存器

CPU执行以上指令时,相当于进行:

push IP

jmp 16位寄存器

转移地址在内存中的call指令

(1) call word ptr 内存单元地址

汇编语法解释:

push IP

jmp word ptr 内存单元地址

(2) call dword ptr 内存单元地址

汇编语法解释:

push CS

push IP

jmp dword ptr 内存单元地址

mul指令

mul是乘法指令,使用 mul 做乘法的时候:

(1)相乘的两个数:要么都是8位,要么都是16位。

  8 位: AL中和 8位寄存器或内存字节单元中;

16 位: AX中和 16 位寄存器或内存字单元中。

使用mul座乘法的时候:

(2)结果

  8位:AX中;

16位:DX(高位)和AX(低位)中。

(3)指令样式

mul reg

mul 内存单元

(4)内存单元可以用不同的寻址方式给出

mul byte ptr ds:[0]

含义为: (ax)=(al)*((ds)*16+0);

mul word ptr [bx+si+8]

含义为:

(ax)=(ax)*((ds)*16+(bx)+(si)+8)结果的低16位;

(dx)=(ax)*((ds)*16+(bx)+(si)+8)结果的高16位;

示例:计算100*10000

100小于255,可10000大于255,所以必须做16位乘法,程序如下:

mov ax,100

mov bx,10000

mul bx

结果: (ax)=4240H,(dx)=000FH(F4240H=1000000)

方法一:

方法二:一直jmp,等到cx的值为0的时候使用jcxz跳出循环(好处,不用我们设置cx的大小了)

方法三:寄存器是有限的,so我们可以使用栈来存放数据

 1 capital: push cx
 2          push si
 3          
 4  change: mov cl,[si]
 5          mov ch,0
 6          jcxz ok
 7          and byte ptr [si],11011111b
 8          inc si
 9          jmp short change
10          
11      ok: pop si
12          pop cx
13          ret

 

以上是关于汇编Call指令问题的主要内容,如果未能解决你的问题,请参考以下文章

[汇编]《汇编语言》第10章 CALL和RET指令

关于汇编call指令的请教

汇编call 命令 解析

汇编语言中的call是啥意思

8086汇编 call 指令

关于汇编指令call和ret的具体细节操作!