assembly 汇编中的标签和函数有什么区别

tez616oj  于 2022-12-13  发布在  其他
关注(0)|答案(3)|浏览(223)

我一直在youtube上通过AT&T语法来学习汇编教程。我刚刚学习了如何用.type指令声明(如果这是正确的术语的话)一个函数,例如:

.type MyFunction, @function

现在我可以定义函数如下:

MyFunction:
    <code here>

然后在以下情况下调用它:

call MyFunction

我知道在教程中,在此之前,我们只是创建了一个附加到某些代码的标签:

MyLabel:
    <code here>

可以这样命名:

call MyLabel

所以我的问题是:
用.type声明的函数和用标签声明的'function'之间到底有什么区别?什么时候应该优先使用一个,或者这有什么关系?

guykilcj

guykilcj1#

下面是binutils文档中关于.type指令的说明(假设您使用的是GNU汇编程序):
此指令用于设置符号的类型。
...
对于ELF目标,.type指令的用法如下:
.type name , type description
根据Symbol Type上的文档:
符号的type属性包含重定位(节)信息、指示符号是外部符号的任何标志设置以及(可选)链接器和调试器的其他信息。确切的格式取决于所使用的对象代码输出格式。
.type MyFunction, @function会将标签MyFunction(符号)标记为连接器或调试工具的函式。
当手工编写纯汇编文件时,这是不必要的。下面是一个file的例子,其中调用了一个itoa函数。正如你所看到的,标签前面没有指令。
总之,标签可以被标记为函数,但对于执行代码来说,它只是一个跳转目标。

pb3skfrl

pb3skfrl2#

就CPU而言,没有什么区别。许多汇编程序根本不要求您声明.type MyFunction, @function;而是把MyFunction放到你想放的地方然后把call MyFunction放到那里。
标签是汇编程序的一个特性,它使汇编程序比以前更好用(例如,用十六进制编辑器输入字节)。

MyFunction:
nop
ret

实际上是一个常量指针,指向直接位于其下的指令,在本例中是nop。根据文件中代码的数量和位置,标签MyFunction等于某个数字,但让汇编程序为我们管理这个数字要容易得多。
想象一下,如果我们没有标签,我们就必须记住MyFunction的地址,而且每次修改程序时,我们都必须用正确的目的地手动更新所有的jmpcall语句,这听起来很糟糕,不是吗?
相对分支的处理方式不同,但最终结果是相同的。

MyFunction:
add eax,ebx
jne MyFunction

jne MyFunction中的MyFunction不是编码为常量地址,而是一个有符号偏移量,它与%rip相加/相减,以使其等于与MyFunction对应的内存位置。
编辑:在x86上,jmpcall也是相对的,就像上面的例子一样,但这并不是所有体系结构的情况。

hgncfbus

hgncfbus3#

我认为无论你使用什么汇编程序,关键点都是return命令。无论你汇编程序中“return”的名字是什么,都可以使用。调用函数与分支的不同之处在于,一些上下文数据(具有N、C、V位的状态寄存器,程序计数器)被推入/存储到堆栈中。当执行返回命令时,从堆栈中恢复数据。这是为了能够在函数调用后保持程序从地址执行。

相关问题