iOS开发者,需要懂一点汇编

245 阅读6分钟

常用的汇编指令(ARM架构)

mov

用于将数据从一个位置移动到另一个位置。它可以用于将立即数、寄存器或者内存中的值复制到寄存器或者内存的另一个位置

指令格式:
mov <Destination>, <Source>
  • <Destination> 是目标位置,可以是寄存器或者内存地址。
  • <Source> 是数据来源,可以是立即数、寄存器或者内存地址。
示例:
mov x1, x0 将寄存器 x0 的值复制到寄存器 x1中
mov x0, #5 将立即数 5 移动到寄存器 x0 中
mov [x2], x1 寄存器 x1 中的值存储到内存地址 x2 处。

add

用于执行加法操作。它可以将两个操作数的值相加,并将结果存储在目标操作数中

指令格式:
add <Destination>, <Operand1>, <Operand2>
  • <Destination> 是目标操作数,存储加法结果的位置,可以是寄存器或者内存地址。
  • <Operand1><Operand2> 是参与加法运算的两个操作数,可以是寄存器、立即数或者内存中的值。
例子:
add x0, x1, x2 将寄存器 x1 和 x2 的值相加后保存到寄存器x0中
add x3, x3, #10 将寄存器 x3 中的值与立即数 10 相加,并将结果存储回寄存器 X3 中
add x4, [x5], #4 将寄存器 x5 中的值作为内存地址,加载该地址处的值加上立即数 4,然后将结果存储到寄存器 x4 中。

sub

用于执行减法操作,和add指令类似

and

用于执行按位与操作。它将两个操作数的对应位进行逻辑与操作,并将结果存储在目标操作数中。和add指令类似

orr

用于执行按位或操作。它将两个操作数的对应位进行逻辑或操作,并将结果存储在目标操作数中。和add指令类似

str

用于将寄存器中的数据存储到内存中的指定地址

指令格式:
str <Register>, [<BaseRegister>, <Offset>]
  • <Register> 是要存储到内存的寄存器中的数据。
  • <BaseRegister> 是基础寄存器,表示存储数据的内存地址的基地址。
  • <Offset> 是偏移量,表示相对于基础寄存器的偏移地址。

str 指令会将寄存器 <Register> 中的数据存储到[<BaseRegister> + <Offset>] 这个内存地址处。

示例:
str x0, [x1, #8] 将寄存器 X0 中的数据存储到地址为 x1 加上偏移量 8 的内存地址处。
strb w2, [x3, #-4] 将寄存器 W2 中的数据存储到地址为 x3 减去偏移量 4 的内存地址处的一个字节中。`strb` 是用于存储一个字节的数据。
str x4, [sp, #16] 将寄存器 x4 中的数据存储到栈指针(sp)加上偏移量 16 的内存地址处。

ldr

用于从内存中加载数据到寄存器中。

指令格式:
ldr <Register>, [<BaseRegister>, <Offset>]

  • <Register> 是要加载数据的目标寄存器。
  • <BaseRegister> 是基础寄存器,表示要加载数据的内存地址的基地址。
  • <Offset> 是偏移量,表示相对于基础寄存器的偏移地址。 ldr 指令会将从内存地址 [<BaseRegister> + <Offset>] 处加载的数据存储到目标寄存器 <Register> 中。
示例:
ldr X0, [X1, #4] 将从地址为 X1 加上偏移量 4 的内存地址处加载的数据存储到寄存器 X0 中
ldrb W2, [X3, #-8] 将从地址为 X3 减去偏移量 8 的内存地址处加载一个字节的数据存储到寄存器 W2 中。`ldrb` 是用于加载一个字节的数据。
ldr X4, [SP, #20] 将从栈指针(SP)加上偏移量 20 的内存地址处加载的数据存储到寄存器 X4 中。

cbz

条件分支指令,用于检查一个寄存器中的值是否为零,并在满足条件时执行跳转

指令格式:
cbz <Register>, <label>
  • <Register> 是要检查的寄存器。
  • <label> 是条件满足时要跳转到的标签。

如果 <Register> 中的值为零,则执行跳转到指定的标签处;如果不为零,则继续执行下一条指令。

示例:
CBZ X0, zero_label

示例:
loop_start:
    ; 这里是循环的代码
    ; 可能会包含条件判断和跳转指令

    CBZ X0, loop_end ; 如果X0为零,跳转到loop_end标签处

    ; 其他指令
    ; ...
    B loop_start ; 无条件跳转回loop_start标签处

loop_end:
    ; 循环结束后的代码

cbnz

和cbz相反,用于检查一个寄存器中的值是否为非零,并在满足条件时执行跳转

cmp

用于比较两个操作数的值,并根据比较结果设置处理器状态寄存器中的标志位,以供后续的条件分支指令使用

指令格式:
cmp <Operand1>, <Operand2>
  • <Operand1><Operand2> 是要进行比较的操作数,可以是寄存器、立即数或者内存中的值。
  • cmp 指令会将 <Operand1> 减去 <Operand2> 的值,并更新处理器状态寄存器中的标志位,但不会保存计算结果。它通常与条件分支指令(比如 BEQBNE 等)一起使用,根据比较结果来执行条件性的跳转或者其他操作。
示例:
cmp X0, #10 比较寄存器 X0 中的值和立即数 10。根据比较结果,会设置处理器状态寄存器中的标志位,
            例如,如果 X0 的值小于 10,则设置相应的标志位,供后续的条件分支指令使用。

bl

用于实现函数调用或跳转到其他代码块

指令格式:
bl <label>
  • <label> 是要跳转到的目标代码块或函数的标签。

bl 指令会将当前指令的下一条指令的地址存储到链接寄存器(LR)中,并跳转到指定标签处执行代码。这个指令用于函数调用或者在程序中执行跳转,同时保留了函数调用前的返回地址,以便函数执行结束后返回到调用它的位置。

示例:
bl 地址/寄存器值

blr

用于无条件跳转到寄存器中存储的地址,并将返回地址存储在链接寄存器(LR)中

指令格式:
blr <Register>
  • <Register> 是包含要跳转地址的寄存器。 BLR 指令会从指定的寄存器中加载地址,然后跳转到该地址处执行代码。在跳转前,它会将下一条指令的地址存储到链接寄存器 LR 中,以便在跳转后能够返回到 BLR 指令后面的位置。
示例:
blr X3 会从寄存器 X3 中加载地址,然后无条件跳转到该地址处执行代码,
       并将 `blr` 指令后面一条指令的地址存储到链接寄存器 LR 中,以便在跳转后返回到 `blr` 指令后面的位置。