目录
一 跳转和调用指令概述
跳转和调用指令 无条件分支指令J具有比条件分支更长的范围(与PC相关)。调用具有稍长的范围,因为它们针对32位对齐的地址。此外,跳转和间接调用指令提供了对案例分派、函数变量和动态链接的支持。 表3-15显示了跳转和调用指令。
指令 | 格式 | 定义 |
---|---|---|
CALL0 | CALL | 调用子例程,与PC相关 |
CALLX0 | CALLX | 调用子例程,地址在寄存器中 |
J | CALL | 无条件跳转,与PC相关 |
JX | CALLX | 无条件跳转,地址在寄存器中 |
RET | CALLX | 子例程返回——跳转到返回地址。用于从由CALL0/CALLX0调用的例程返回。 |
二 跳转和调用指令详述
以下是关于Xtensa汇编中的跳转和调用指令的一些信息:
1 CALL0:
- CALL0: 这是一种与PC相关的调用子例程的指令。它将当前PC值保存到返回地址寄存器,并跳转到目标地址执行子例程。格式如下:
assembly
深色版本
1CALL0 target_label
这里的target_label
是子例程的标签。注意,CALL0
只适用于短距离跳转,适合于在同一函数或附近函数之间跳转。
2 CALLX0
- CALLX0: 这是一种调用子例程的指令,地址在寄存器中。它将当前PC值保存到返回地址寄存器,并跳转到寄存器中的地址执行子例程。格式如下:
assembly
深色版本
1CALLX0 reg
这里的reg
是要跳转的地址所在的寄存器。
3 J
- J: 这是一种无条件跳转指令,与PC相关。它跳转到目标地址继续执行。格式如下:
assembly
深色版本
1J target_label
这里的target_label
是跳转的目标标签。J
指令的跳转范围比CALL0
更大,适合于较远距离的跳转。
4 JX:
- JX: 这是一种无条件跳转指令,地址在寄存器中。它跳转到寄存器中的地址继续执行。格式如下:
assembly
深色版本
1JX reg
这里的reg
是要跳转的地址所在的寄存器。JX
指令允许更大的跳转范围,适合于非常远的距离。
5 RET:
- RET: 这是一种子例程返回指令。它从返回地址寄存器中取出地址,跳转到那里继续执行。格式如下:
assembly
深色版本
1RET
RET
指令用于从子例程返回到调用者。它通常用于CALL0
或CALLX0
后的返回。
注意事项:
- 所有这些指令都涉及跳转或调用另一个子例程,所以在使用它们之前,确保已经正确设置了所需的参数和保存了必要的状态。
- 当使用
CALL0
和CALLX0
时,目标地址必须在一定范围内,否则会导致错误。J
和JX
的范围更广,但仍然有限制。 CALL0
和CALLX0
会保存当前PC值到返回地址寄存器,以便在子例程结束后能够返回。J
和JX
不会保存返回地址,因此不能直接用来调用子例程。RET
指令用于从子例程返回,它期望返回地址寄存器中有正确的地址。如果没有调用CALL0
或CALLX0
,使用RET
可能会导致未定义的行为。
模板:
assembly
深色版本
1; 使用CALL0调用子例程
2call_subroutine:
3 ; 子例程代码...
4 RET
5
6main:
7 ; ...
8 CALL0 call_subroutine
9 ; 继续执行主程序...
assembly
深色版本
1; 使用CALLX0调用子例程
2call_subroutine:
3 ; 子例程代码...
4 RET
5
6main:
7 ; ...
8 MOVI a0, &call_subroutine
9 CALLX0 a0
10 ; 继续执行主程序...
assembly
深色版本
1; 使用J跳转
2label:
3 ; 目标代码...
4
5main:
6 ; ...
7 J label
8 ; 不会到达这里...
assembly
深色版本
1; 使用JX跳转
2label:
3 ; 目标代码...
4
5main:
6 ; ...
7 MOVI a0, &label
8 JX a0
9 ; 不会到达这里...
assembly
深色版本
1; 使用RET返回
2call_subroutine:
3 ; 子例程代码...
4 RET
5
6main:
7 ; ...
8 CALL0 call_subroutine
9 ; 继续执行主程序...
这些模板展示了如何使用各种跳转和调用指令。实际应用时,应根据具体情况修改这些模板。