通过之前的几篇文章,我们了解了汇编语言的基本语法和变量的使用、寻址方式等,但我们的程序到目前为止,都只局限在_main
内,既没有函数调用,也没有控制结构,进了_main
以后一条路走到retq
. 在这篇文章中,我主要介绍的是汇编语言中的控制结构——跳转,与函数调用。不过在介绍这两个之前,首先需要介绍的是跳转与函数调用的基础——标签。
标签
标签(Label), 是汇编语言中一个重要的组成部分。我们之前在__DATA
段__data
节里定义变量的时候,就使用了标签。我们通常使用的标签,定义时是以冒号:
结尾的一个标识符,且开头不能是数字。LBB0:
, a:
, _func:
, _main:
都是标签的定义。
我们可以在.data
段,也可以在.text
段定义标签,只需要在那里写上标签加上:
即可。比如说,
loop_begin: movq $0x114514, %rax
jmp loop_begin
就定义了一个标签loop_begin
, 并且在下一条指令中使用了它. 接下来任何一个地方使用到loop_begin
, 就代表这个指令所处的地址。
一般来说,定义的标签只能在同一个汇编文件中使用,如果一个汇编文件想使用另一个汇编文件定义的标签,需要另一个汇编文件用.globl
声明标签是全局可见的,比如说.globl _main
.
跳转
在介绍完标签之后,就可以解释跳转了。跳转分为无条件跳转与条件跳转。我们首先介绍无条件跳转。
无条件跳转
无条件跳转对应的助记符是jmp
. 其操作数是标签。jmp loop_begin
就是跳转到loop_begin
标记的位置。这里就有一个问题,这样的跳转,是不是position indenpendent的呢?答案是是的。但是和之前PC-relative的技巧不同,这里PIC的方法不是程序员做的,而是汇编器做的。汇编器会直接将jmp
翻译成相对跳转的机器码,对程序员来说是透明的。所以,我们并不需要太过关心这里的PIC.
我们使用无条件跳转的时候要特别注意,因为极易造