在arm指令中经常出现SWI 0x123456指令,这条指令代表什么意思

在arm指令中经常出现SWI 0x123456指令,这条指令代表什么意思,第1张

软中断指令,后面用24位立即数表示软中断类型,cpu遇到这条指令会跳转到中断向量表中软中断指令处,然后根据那条指令跳转到swi handler,在swi handler中需要通过LR寄存器,用指令
LDR R0,[LR,#-4];BIC R0,R0,#0xff000000来获得那个24位立即数(LR中保存的是SWI 0x123456的下一条指令地址,也就是软中断返回地址),然后做进一步处理

参考ARM体系结构与编程

0X3FC=00000000,00000000,00000011,11111100,共32位。
0XFF =00000000,00000000,00000000,11111111,也是32位。
你看一下,0X3FC循环左移30位,也就是循环右移2位,是不是等于0XFF
之前说的合法和不合法,指的是:
在32位的二进制中,第一个“1”和最后一个“1”,
跨度大于8位,就是不合法。(比如0x101,分开来,跨度是9个位置了)
跨度小于8为,就合法。(比如0xF000000F,虽然本来是跨度很大的,如果循环左移或右移4位,跨度刚好是8个位置。)
我也是初学,不知道,说的明白没有?

我在前一秒终于想明白了这个问题,由于arm指令是固定32位(4字节)的,表示立即数的只有12位,而要表达32位的立即数,就必须用多条指令才行,假如按常规思路,立即数0xFFFFFFFF则这样表达:

Rn = 立即数高12位

Rn <<= 12                <--------这里浪费8位立即数空间,因为12=1010

Rn |=立即数后12位

Rn <<=12                <--------这里浪费8位立即数空间,因为12=1010

Rn |=立即数低8位    <--------这里浪费4位立即数空间

这样用5条指令才能将32位的立即数放入Rn寄存器中,而这样占用的内存=20字节,显然整个指令链太长,而且浪费bit位。

而arm的设计正是考虑到了这一点,想出了这个很绕人的解决办法,且没有说明思路,导致这里成为了大家的困惑。下面是我分析。

机器码中立即数出现得最多的用途是地址,而arm 中要求地址是偶数对齐。

4位二进制数只能右移动16位,显然不能把立即数8位完全移动到32位的高24位,所以只好采用先将4位扩展位5位的办法,即2处理,这样就可以把8位立即数按2粒度移动到32位任一位置,这样我们只需控制8位的立即数,就可形成任意32位立即数。

arm 用上面的5位直接在其内部按位寻址寄存器相应的位,免去了程序中的位移 *** 作,而代价只是编译过程稍微复杂了点。

这样最多用4条指令就可完成上面的例子。

你好,我是学嵌入式的,刚学过arm汇编,对与这个问题应该是不做区分的,
我们这样来看
0xFFFFFFFFFFFFFFFF=-1也==18446744073709551615
它在储存区域里都是一样的,arm汇编不能声明和定义它,
但是我做了个这样的实验
AREA A,CODE,READONLY
ENTRY
START
MOV R1,#-2;
MOV R2,#3
ADD R3,R1,R2
end
B end
END
最后R3的结果1,cpsr没有反应,也就是它做出了处理,为什么会这样呢我个人研究理解是编译器做的
一条arm指令分为几个部分
<opcode> {<conde>} {s} <rd>,<rn>,<op2>
你发现没有一条arm指令32位有多少位用来存rd,rn,op2 *** 作数只有8位 也就是最大只能用0xff的立即数,但是arm指令也作了一定的改进,就是循环左移,
也就是你可以用一个最多只有连续两位不等于0的16进制数如0xff00000,,0x00ff00
0xF100是对的,这样的立即数是会抱错的-->0xabc,0x0b010
也就是你用mov付值的时候 可以这样做,MOV R1,#-1
但你不能这样MOV R1,#0xFFFFFFFFFFFFFFFF
可能是编译器在发现一个负数与正数相加的时候就做了改动
以后大家相互学习QQ:19999243

立即数:

一个立即数是一块数据存储作为指令本身,而不是在一个中的一部分内容存储器位置或寄存

器。立即值通常用于加载值或对常量执行算术或逻辑运算的指令。

概述:

在大多数指令集架构下,各种指令也可以对常量值执行 *** 作。例如,考虑一个可以添加两个寄

存器并将结果存储在第三个寄存器中的ISA:

添加 r3,r2,r1; r3 = r2 + r1

指令集还可以支持添加常量值的常见情况(例如,在许多支持++ var的编程语言的情况下)。

添加r1,r1,1; r1 = r1 + 1

在上面的代码中,值1是在add指令本身中编码的立即数。

扩展资料:

立即数的实施限制:

由于立即数被打包到指令本身中,因此某些ISA具有可用作立即值的受限范围的值。例如,在

MIPS32中,立即数限制为16位。在一些更复杂的体系结构(如ARM)上,某些指令可能接受

16位值,其他指令可能接受较小的范围,并且能够根据需要旋转位。

在立即数不能直接编码到指令中的情况下,例如当值超出范围时,可以采用各种其他方式来处

理这些值。一个这样的选项是从内存中的常量池(例如文字池)加载公共值。或者,可以使用

可以表示或加载到寄存器中并从那里 *** 作的值来组装值。一些ISA(如MIPS32和ARM)具有

专用指令,如LUI,MOVW和MOVT,它们提供了一种方法,将高16位后跟低16位加载到单个

寄存器中。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/13351040.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-19
下一篇 2023-07-19

发表评论

登录后才能评论

评论列表(0条)

保存