有条件调用子程序汇编 [英] call subroutines conditionally in assembly

查看:116
本文介绍了有条件调用子程序汇编的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在学习x86汇编。我想知道你是如何进行有条件地调用一个子程序。
据我了解,跳转到一个标签不起作用,因为返回地址没有保存,因此它不知道从哪里回来。

  CMP BX,0
 JZ为零;我怎么正确地做到这一点?
 ;做别的事情,然后退出 零:
 ;做一点事
 RET


解决方案

那么它如果你不需要返回到该地址的作品。很多时候,你可以组织你的code,使得这种情况。

否则,你就必须做 JXX ,围绕呼叫网站或者以其他方式组织你的code解决此限制跳转指令分支。在这种情况下,反向测试应该工作:

  CMP BX,0
    JNZ not_zero
    调用零
    ;砸锅这里,返回或做你想做的
not_zero:
    ;做别的事情,然后退出
    ; ...
    RET零:
    ;做一点事
    RET

编辑2016年4月25日:作为@Peter科德斯在评论中提到,下面的code可能会进行了苦头。例如参见一个解释这是为什么。的<这篇文章 / p>

在评论@Manny Ds的建议启发我写了下面。它可能不是清洁剂或更好的,但它是另一种方式来构建的:

 推back_from_zero;按我们想以后可能转移到零回归
    CMP BX,0
    JZ为零;如果分公司BX == 0
    ADD ESP,4;在我们没有分支的情况下调整堆栈
back_from_zero:;从零分支返回这里或从上面继续
    ;做别的事情,然后退出零:
    ;做一点事
    RET

它明确地推栈上的返回地址,让函数可以返回或弹出值( ADD ESP,4 )(重新调整堆栈)。请注意,您需要做一些微调,如果你想这在任何16位或64位模式下运行。

I'm learning x86 assembly. I was wondering how you perform call a subroutine conditionally. As far as I understand, jumping to a label doesn't work because the return address is not stored and therefore it does not know where to return.

 cmp bx, 0
 jz zero ; how do I do this correctly ?
 ; do something else and exit

 zero:
 ; do something
 ret

解决方案

Well it works if you don't need to return to that address. Often times you can structure your code such that this is the case.

Otherwise you'll have to do the branching with Jxx instructions that jump around the call site or in other ways structure your code around this limitation. In this case inverting the test should work:

    cmp bx, 0
    jnz not_zero
    call zero
    ; fall through here, return or do what you want
not_zero:
    ; do something else and exit
    ; ...
    ret 

zero:
    ; do something
    ret

EDIT 2016-04-25: As @Peter Cordes mentions in the comments, the below code will probably perform terribly. See e.g. this article for an explanation why.

@Manny Ds suggestion in the comments inspired me to write the following. It might not be cleaner or better, but it's another way to structure it:

    push back_from_zero ; Push where we want to return after possibly branching to 'zero' 
    cmp bx, 0
    jz zero ; branch if bx==0
    add esp, 4 ; adjust stack in case we didn't branch
back_from_zero: ; returning from the zero branch here or continuing from above
    ; do something else and exit

zero:
    ; do something
    ret

It explicitly pushes the return address on the stack so the zero function can return or pops the value (add esp, 4) from the stack if we don't call the function (to readjust to stack). Note that you need to do some slight adjustments if you want this to work in either 16- or 64-bit mode.

这篇关于有条件调用子程序汇编的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆