Linux教程

第11部分- Linux ARM汇编 执行分支

本文主要是介绍第11部分- Linux ARM汇编 执行分支,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

在32位的ARM架构系统中,通用寄存器中有一个寄存器比较特殊,就是r15,它也是PC寄存器。

PC是program counter。也叫做ip,instruction pointer。

当ARM处理器执行一条指令时,在其执行结束时可能会发生两件事。 如果指令没有修改pc,则pc只会增加4,因为在32位ARM中,指令为32位宽,所以每条指令之间有4个字节。 如果指令修改了pc,则使用pc的新值。当然64位的ARM就是增加8了每次指令过后。

如果一条指令确实将pc修改为例如pc + 4以外的其他值,那么可以运行该程序的另一条指令。 更改pc值的过程称为分支。 在ARM中,这是使用分支指令完成的。

      可以分为无条件分支和有条件分支。

无条件分支就是强制跳转了,我们主要来看下有条件分支。

有条件分支

这里涉及到一个寄存器cpsr(urrent Program Status Register)。

其包含条件flag:

N (negative), Z (zero), C (carry) and V (overflow)

N:如果指令结果为负数,则启用,否则禁用。

Z:如果指令的结果为零,则将启用。 如果非零,则禁用。

C:如果指令的结果产生的值需要完全表示第33位,则将启用C。 例如,加法溢出了32位整数范围。 对于减法,有一个特殊情况,即无借位减法使能C,否则将其禁用:否则,将较大的数减为较小的值将启用C,但如果反之亦然,则将其禁用。

V:如果指令结果产生的值不能用32位二进制补码表示,则将启用V。

汇编指令

32位示例

.text
.global main
main:
    mov r1, #2       /* r1 ← 2 */
    mov r2, #2       /* r2 ← 2 */
    cmp r1, r2       /* update cpsr condition codes with the value of r1-r2 */
    beq case_equal   /* branch to case_equal only if Z = 1 */
case_different :
    mov r0, #2       /* r0 ← 2 */
    b end            /* branch to end */
case_equal:
    mov r0, #1       /* r0 ← 1 */
end:
    bx lr
复制代码

as -g -o com.o com.s

ld -o com com.o

当r1和r2寄存器相等的时候才会跳转。

64位示例

我们再来看下64位的示例代码。

.arch armv8-a
.global _start
.text
_start:

    mov x1, #2       /* r1 ← 2 */
    mov x2, #2       /* r2 ← 2 */
    cmp x1, x2       /* update cpsr condition codes with the value of r1-r2 */
    beq case_equal   /* branch to case_equal only if Z = 1 */
case_different :
    mov x0, #2       /* r0 ← 2 */
    b end            /* branch to end */
case_equal:
    mov x0, #1       /* r0 ← 1 */

	mov x8, 93
	svc 0
复制代码

as -g -o com64.o com64.s

ld -o com64 com64.o



这篇关于第11部分- Linux ARM汇编 执行分支的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!