16
|
Summer_More_More_Tea · 技术社区 · 15 年前 |
![]() |
1
13
记住,ARM可以对即时值执行特定的操作集,作为合并到ARM操作码中的桶移位器的一部分。 这篇小文章对ARM汇编程序可以用来将大量即时数放入ARM指令的小可用空间的一些技巧进行了最清晰的解释: 本文讨论了在生成MVN操作码以加载即时值的位补码的特定示例中可能使用的技巧。 这些类型的操作不能用所有的即时值来完成,但是ARM汇编程序被认为是非常聪明的(C编译器当然是这样)。如果无法执行移位/补码技巧,则通常会从PC相关位置加载该值,或者通过从多个指令中“构建”该值来加载该值。 |
![]() |
2
11
单臂指令只能对一个立即数常量进行编码,该常量可以表示为一个8位立即数,由任意移位。 即使 二的力量。
但是,还有一个
|
![]() |
3
2
MOV指令可以接受imm16值或operator2值(由于指令长度与内存对齐相反),这必须符合以下任何规则(从Cortexm指令集手册复制,x和y是任何十六进制值):
这就是为什么接受0xffffffff(符合第4条规则)。 如果您希望组装自己的32位常量,可以使用指令 莫特 写入寄存器的上半部分。 |
![]() |
4
1
您可能会看到原始值的符号扩展中的工件。如果用于查看反汇编的工具将0..255作为有符号字节处理,那么当它将其加载到更大的int类型(或寄存器)时,它将用原始值的符号位填充所有的高位。或者换句话说,如果0xff是有符号字节,则其十进制值为-1。把它放入一个32位寄存器,十六进制看起来像0xffffffff,它的十进制值仍然是-1。 尝试使用不带高位集的值,如0x7F。由于未设置符号位,因此我猜想当加载到更大的int类型寄存器或字段时,它将用零填充高位。 编译器/汇编程序也可能截断您提供的任何值。我会认为这是源代码错误,但汇编程序是有趣的野兽。如果给它0x7ff,它编译为0x7ff(未截断,且大于0..255)还是0xffffffff(截断为0..255,有符号字节)? |
![]() |
5
1
很难确定给定的常量是否在有效范围内。 正如Matthew已经提到的,汇编程序通过用类似的、否定的指令(如mov/mvn、cmp/cmn、tst/tne等)替换给定的指令来帮助您。 |
![]() |
6
-1
一种可能是ARM汇编程序丢弃了数字的有效位,只使用最低的FF。 MOV指令是许多CPU指令集中的主食,通常汇编程序解析目标寄存器的大小和所提供的立即值。 例如,来自x86集的以下MOV指令是
|
![]() |
Daniel · 仅在-O3中进行未对齐的内存访问 1 年前 |
![]() |
TRElec · STM32:代码的执行似乎取决于它在闪存中的位置 2 年前 |
![]() |
Marietto · FATAL:ThreadManitizer:不支持的VMA范围FATAL:找到39-支持的48/go:添加了github.com/docker/docker v23.0.4+不兼容 2 年前 |
![]() |
Ilya Loskutov · 无法将单词加载到寄存器中 3 年前 |