arm基础汇编指令小结
来源:互联网 发布:windows阻止此软件 编辑:程序博客网 时间:2024/05/16 15:31
arm汇编指令:
1、算术和逻辑指令 2、比较指令3、跳转指令 4、移位指令5、程序状态字访问指令 6、存储器访问指令
1、算术和逻辑指令
MOV : 传送
(Move)
MOV{条件}{S} <dest>, <op 1> dest = op_1
MOV
从另一个寄存器、被移位的寄存器、或一个立即值装载一个值到目的寄存器。你可以指定相同的寄存器来实现 NOP 指令的效果,你还可以专门移位一个寄存器:MOV R0, R0 ; R0 = R0... NOP 指令 MOV R0, R0, LSL#3 ; R0 = R0 * 8如果 R15 是目的寄存器,将修改程序计数器或标志。这用于返回到调用代码,方法是把连接寄存器的内容传送到 R15:
MOV PC, R14 ; 退出到调用者 MOVS PC, R14 ; 退出到调用者并恢复标志位 (不遵从 32-bit 体系)
MVN : 传送取反的值
(Move Negative)
MVN{条件}{S} <dest>, <op 1> dest = !op_1
MVN
从另一个寄存器、被移位的寄存器、或一个立即值装载一个值到目的寄存器。不同之处是在传送之前位被反转了,所以把一个被取反的值传送到一个寄存器中。这是逻辑非操作而不是算术操作,这个取反的值加 1 才是它的取负的值:MVN R0, #4 ; R0 = -5 MVN R0, #0 ; R0 = -1
SUB : 减法
(Subtraction)
SUB{条件}{S} <dest>, <op 1>, <op 2> dest = op_1 - op_2
SUB
用操作数 one 减去操作数 two,把结果放置到目的寄存器中。操作数 1 是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即值:SUB R0, R1, R2 ; R0 = R1 - R2 SUB R0, R1, #256 ; R0 = R1 - 256 SUB R0, R2, R3,LSL#1 ; R0 = R2 - (R3 << 1)减法可以在有符号和无符号数上进行。
ADD : 加法
(Addition)
ADD{条件}{S} <dest>, <op 1>, <op 2> dest = op_1 + op_2
ADD
将把两个操作数加起来,把结果放置到目的寄存器中。操作数 1 是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即值:ADD R0, R1, R2 ; R0 = R1 + R2 ADD R0, R1, #256 ; R0 = R1 + 256 ADD R0, R2, R3,LSL#1 ; R0 = R2 + (R3 << 1)加法可以在有符号和无符号数上进行。
AND : 逻辑与
(logical AND)
AND{条件}{S} <dest>, <op 1>, <op 2> dest = op_1 AND op_2
AND
将在两个操作数上进行逻辑与,把结果放置到目的寄存器中;对屏蔽你要在上面工作的位很有用。 操作数 1 是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即值:AND R0, R0, #3 ; R0 = 保持 R0 的位 0 和 1,丢弃其余的位。AND 的真值表(二者都是 1 则结果为 1):
Op_1 Op_2 结果 0 0 0 0 1 0 1 0 0 1 1 1
BIC : 位清除
(Bit Clear)
BIC{条件}{S} <dest>, <op 1>, <op 2> dest = op_1 AND (!op_2)
BIC
是在一个字中清除位的一种方法,与 OR 位设置是相反的操作。操作数 2 是一个 32 位位掩码(mask)。如果如果在掩码中设置了某一位,则清除这一位。未设置的掩码位指示此位保持不变。BIC R0, R0, #%1011 ; 清除 R0 中的位 0、1、和 3。保持其余的不变。BIC 真值表 :
Op_1 Op_2 结果 0 0 0 0 1 0 1 0 1 1 1 0
2、比较指令
CMP : 比较
(Compare)
CMP{条件}{P} <op 1>, <op 2> status = op_1 - op_2
CMP
允许把一个寄存器的内容如另一个寄存器的内容或立即值进行比较,更改状态标志来允许进行条件执行。它进行一次减法,但不存储结果,而是正确的更改标志。标志表示的是操作数 1 比操作数 2 如何(大小等)。如果操作数 1 大于操作操作数 2,则此后的有 GT 后缀的指令将可以执行。明显的,你不需要显式的指定
S
后缀来更改状态标志... 如果你指定了它则被忽略。
TST : 测试位
(Test bits)
TST{条件}{P} <op 1>, <op 2> Status = op_1 AND op_2
TST
类似于 CMP
,不产生放置到目的寄存器中的结果。而是在给出的两个操作数上进行操作并把结果反映到状态标志上。使用TST
来检查是否设置了特定的位。操作数 1 是要测试的数据字而操作数 2 是一个位掩码。经过测试后,如果匹配则设置 Zero 标志,否则清除它。象CMP
那样,你不需要指定 S
后缀。TST R0, #%1 ; 测试在 R0 中是否设置了位 0。
3、跳转指令
B : 分支
(Branch)
B{条件} <地址>
B
是最简单的分支。一旦遇到一个 B
指令,ARM 处理器将立即跳转到给定的地址,从那里继续执行。注意存储在分支指令中的实际的值是相对当前的 R15 的值的一个偏移量;而不是一个绝对地址。它的值由汇编器来计算,它是 24 位有符号数,左移两位后有符号扩展为 32 位,表示的有效偏移为 26 位(+/- 32 M)。在其他处理器上,你可能经常见到这样的指令:
OPT 1 LDA &70 CMP #0 BEQ Zero STA &72 .Zero RTS(取自 Acorn Electron User Guide issue 1 page 213)
在 ARM 处理器上,它们将变成下面这些东西:
OPT 1 ADR R1, #&70 LDR R0, [R1] CMP #0 BEQ Zero STR R0, [R1, #2] .Zero MOV PC, R14这不是一个很好的例子,但你可以构想如何更好的去条件执行而不是分支。另一方面,如果你有大段的代码或者你的代码使用状态标志,那么你可以使用条件执行来实现各类分支: 这样一个单一的简单条件执行指令可以替代在其他处理器中存在的所有这些分支和跳转指令。
OPT 1 ADR R1, #&70 LDR R0, [R1] CMP R0, #0 STRNE R0, [R1, #2] MOV PC, R14
BL : 带连接的分支
(Branch with Link)
BL{条件} <地址>
BL
是另一个分支指令。就在分支之前,在寄存器 14 中装载上 R15 的内容。你可以重新装载 R14 到 R15 中来返回到在这个分支之后的那个指令,它是子例程的一个基本但强力的实现。它的作用在屏幕装载器 2 (例子 4)中得以很好的展现....load_new_format BL switch_screen_mode BL get_screen_info BL load_palette .new_loop MOV R1, R5 BL read_byte CMP R0, #255 BLEQ read_loop STRB R0, [R2, #1]!...在这里我们见到在装载器循环之前调用了三个子例程。接着,一旦满足了条件执行就在循环中调用了 read_byte 子例程。
4、移位指令
逻辑或算术左移
(Logical or ArithmeticShift Left)
Rx, LSL #n or Rx, ASL #n or Rx, LSL Rn or Rx, ASL Rn接受 Rx 的内容并按用‘n’或在寄存器 Rn 中指定的数量向高有效位方向移位。最低有效位用零来填充。除了概念上的第 33 位(就是被移出的最小的那位)之外丢弃移出最左端的高位,如果逻辑类指令中 S 位被设置了,则此位将成为从桶式移位器退出时进位标志的值。
考虑下列:
MOV R1, #12 MOV R0, R1, LSL#2在退出时,R0 是 48。 这些指令形成的总和是
R0 = #12, LSL#2
等同于 BASIC 的 R0 = 12 << 2
循环右移
(Rotate Right)
Rx, ROR #n or Rx, ROR Rn循环右移类似于逻辑右移,但是把从右侧移出去的位放置到左侧,如果逻辑类指令中 S 位被设置了,则同时放置到进位标志中,这就是位的‘循环’。一个移位量为 32 的操作将导致输出与输入完全一致,因为所有位都被移位了 32 个位置,又回到了开始时的位置!
5、程序状态字访问指令
操纵 32 位 PSR 的指令
你不能在 32 位模式中使用 MOVS PC, R14
或 LDMFD R13!, {registers, PC}^
。也不能使用ORRS PC, R14, #1<<28
来设置 V 标志。现在需要使用 MRS
和 MSR
。
复制一个寄存器到 PSR 中 MSR CPSR, R0 ; 复制 R0 到 CPSR 中 MSR SPSR, R0 ; 复制 R0 到 SPSR 中 MSR CPSR_flg, R0 ; 复制 R0 的标志位到 CPSR 中 MSR CPSR_flg, #1<<28 ; 复制(立即值)标志位到 CPSR 中
复制 PSR 到一个寄存器中 MRS R0, CPSR ; 复制 CPSR 到 R0 中 MRS R0, SPSR ; 复制 SPSR 到 R0 中指令格式
你有两个 PSR - CPSR
是当前的程序状态寄存器(Current Program Status Register),而 SPSR
是保存的程序状态寄存器(Saved Program Status Register)(前面的处理器模式的 PSR)。每个有特权的模式都有自己的 SPSR,可获得的 PSR 有:
- CPSR_all - 当前的
- SPSR_svc - 保存的,SVC(32) 模式
- SPSR_irq - 保存的,IRQ(32) 模式
- SPSR_abt - 保存的,ABT(32) 模式
- SPSR_und - 保存的,UND(32) 模式
- SPSR_fiq - 保存的,FIQ(32) 模式
_flg
后缀允许你改变标志位而不影响控制位。在 user(32) 模式中,保护 CPSR 的控制位,你只能改变条件标志。在其他模式中,可获得整个 CPSR。你不应该指定 R15 为一个源寄存器或一个目标寄存器。最后,在 user(32) 模式中,你不能尝试访问 SPSR,因为它不存在!
要设置 V 标志:
MSR CPSR_flg, #&10000000这将设置 V 标志但不影响控制位。
要改变模式:
MRS R0, CPSR_all ; 复制 PSR BIC R0, R0, #&1F ; 清除模式位 ORR R0, R0, #new_mode ; 把模式位设置为新模式 MSR CPSR_all, R0 ; 写回 PSR,变更模式
现在我们要做的是进入 SVC32 模式并设置 Z 标志。接着我们返回 SVC26 模式并‘测试’是否设置了 Z。
RISC OS 不希望发现自己处在 32 位模式中,所以我们要禁止所有中断并保持它们这样(keep them that way)。尽管这些代码应该执行的非常快,但我们不应当冒任何风险...
- arm基础汇编指令小结
- ARM汇编指令基础
- ARM汇编指令基础总结
- ARM:ARM汇编语言与基础汇编指令
- ARM汇编基础-存储和加载指令
- ARM 汇编伪指令
- ARM汇编指令集
- GNU ARM汇编指令
- 常用ARM汇编指令
- ARM汇编指令集
- ARM汇编伪指令
- ARM汇编伪指令
- ARM汇编指令集
- ARM汇编伪指令
- GNU ARM 汇编指令
- ARM汇编指令集
- arm 汇编指令 积累
- ARM汇编指令集
- 回车和换行,以及不同软件对敲回车键的操作
- eclipse中使用junit
- hdu1102——Constructing Roads(prim)
- hdoj-2005-第几天?(解题报告)
- 常见异常
- arm基础汇编指令小结
- LeetCode 200 Number of Islands(DFS)
- 设置root密码为“123456”后,直接连localhost密码为空可连,用123456连不上,为啥?
- 2017第八届蓝桥杯C/C++ B组省赛题解、答案
- Time Series Forecasting with the Long Short-Term Memory Network in Python
- First Unique Character in a String问题及解法
- mysql数据库数据同步
- hibernate中的N+1问题
- poj 1125 Stockbroker Grapevine (Floyd)