Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 为什么可以';t 16位指令访问通用寄存器的高位寄存器_Assembly_Arm_Cpu Registers_Instruction Set_Thumb - Fatal编程技术网

Assembly 为什么可以';t 16位指令访问通用寄存器的高位寄存器

Assembly 为什么可以';t 16位指令访问通用寄存器的高位寄存器,assembly,arm,cpu-registers,instruction-set,thumb,Assembly,Arm,Cpu Registers,Instruction Set,Thumb,所以现在我读了《ARM Cortex-M3/M4最终指南》一书,不明白为什么16位指令不能访问高通用寄存器R8-R12 它说,实际上很少有人能访问这些寄存器,但大多数不能。16位意味着机器代码指令只有16位来编码信息。8个寄存器需要3位编码。12个寄存器需要4位编码。然后我们需要为操作码和其他选项留出空间,这意味着额外的位可能太多了。编码8个寄存器的地址需要3位。编码12个寄存器的地址需要4位 如果您有一条3寄存器指令,则需要12位对3个寄存器进行编码,这只为指令留下4位。最多只能有16条指令。

所以现在我读了《ARM Cortex-M3/M4最终指南》一书,不明白为什么16位指令不能访问高通用寄存器R8-R12


它说,实际上很少有人能访问这些寄存器,但大多数不能。16位意味着机器代码指令只有16位来编码信息。8个寄存器需要3位编码。12个寄存器需要4位编码。然后我们需要为操作码和其他选项留出空间,这意味着额外的位可能太多了。

编码8个寄存器的地址需要3位。编码12个寄存器的地址需要4位


如果您有一条3寄存器指令,则需要12位对3个寄存器进行编码,这只为指令留下4位。最多只能有16条指令。

这些核心的唯一实际最终指南是arm文档。在阅读任何其他内容或学习指令集之前,您需要有文档;在这种情况下,请参阅ARMV7-m的ARM架构参考手册以及cortex-m3或cortex-m4技术参考手册。如果你的书做出了这样的陈述,但没有对其进行解释,那就远没有定论

这在技术上是可能的,但它会占用大量空间,可能会破坏尝试16位指令的目的(并不意味着16位处理器或寄存器或类似的东西,指令本身是16位的)。若您查看编译后的代码以及编译器是如何工作的,则生成的大量代码使用较低的寄存器,或者可以这样生成。因此,这是指令集的丰富性与指令数量之间的权衡,这与您拥有的寄存器数量无关

寄存器的大小是无关的,寄存器的数量才是重要的。例如为了

add r1,r2,r3
你必须在某个地方对哪个寄存器进行编码。注释当然是针对旧的/原始的16位指令,而不是thumb2扩展

所以你需要一个模式,自然会:

000 r0
001 r1
010 r2
011 r3
100 r4
101 r5
110 r6
111 r7
如果您将自己限制为8个寄存器,那么每个寄存器只需要3位来描述每个字段使用哪个寄存器

如果要在指令中使用16个寄存器,则需要4位:

0000 r0
0001 r1
0010 r2
....
0111 r7
1000 r8
1001 r9
....
1110 r14
1111 r15
如果指令集中需要32个寄存器(通常不是ARM thumb),则五位:

00000 r0
00001 r1
10000 r16
11111 r31

等等

如果你想描述8件事,需要3位;如果你想描述16件事,需要4位

16位表示可能有65536条唯一指令。ARM的doc很好地展示了它如何布局它的指令集,它倾向于最大化指令的数量和可能的功能,而MIPS则倾向于先简化解码逻辑,然后简化功能(设计权衡)

向前跳过,例如,指令的前6位是操作码

00xxxx shift, add, subtract, move, and compare
010000 data processing instructions
010001 special data
01001x ...
等等。根据您下载的ARM,以各种方式显示

他们不必实现任何三个寄存器指令,但他们选择了实现。如果这些指令对每个操作数都支持r0到r15,那么这意味着需要12位,剩下4位用于编码,包括一个或多个用于指示此类指令和其余操作数的指令,您可能会删除至少一半可能的指令(一位专用于指示这是否为三寄存器指令)留下7个可能的操作或四分之一的指令空间(两位)留下2位来选择哪一个操作数,使其功能不太丰富。相反,他们实际做的是占用指令空间的1/4,但留下至少5位用于操作数和/或其他功能(立即数等)

所以add的T1编码是

0001100mmmnnnddd
前两位表示这是哪一组指令,如果你看一下,你会看到第10位表示立即数或寄存器mmm位是寄存器或介于0和7之间的立即数,很多时候程序员想要增加1或2或一些小数字,必须强制一条指令并烧录一个寄存器才能将其放入小数字与消耗一些指令空间的权衡是一种平衡

无论如何,您可以在这里看到,对于这个指令编码,rm、rn和rd寄存器有三个位。(添加rd、rn、rm),这表明r0-r7对于这些字段中的任何一个都是可能的

为了使它更完整,有一个mov高寄存器指令,允许您移动高/低、低/高或高/高、技术上的低/低,但他们希望您使用不同的编码,如文档所述。其中之一可以是与上述三个寄存器相关的add rd、rn、#0。这就是您看到gnu assembler所做的

.thumb
mov r1,r2
mov r10,r2
mov r1,r11
mov r10,r11
    
00000000 <.text>:
   0:   1c11        adds    r1, r2, #0
   2:   4692        mov r10, r2
   4:   4659        mov r1, r11
   6:   46da        mov r10, r11
.thumb
mov r1,r2
mov r10,r2
mov r1,r11
mov r10,r11
00000000 :
0:1c11加上r1,r2,#0
2:4692 mov r10,r2
4:4659 mov r1,r11
6:46da mov r10,r11
关键是,有一种方法可以在高位寄存器之间来回移动,比在堆栈之间来回移动更快(无内存周期),因此编译器仍然可以选择使用一个或多个高位寄存器(理解push/pop由于明显的原因(读取文档)而受到限制,因此保存和恢复它们会有成本,这是一种折衷)

因此,你应该坚持实际的权威指南,而不是声称是的东西

除非你当时碰巧在大脑/立方体/办公室/会议室,否则你几乎找不到任何地方。设计者实施指令集或特定指令的原因是他们为什么这么做。(为什么没有三个寄存器和,异或,等等)因此,尽管有其他的答案、评论和以上,这是因为他们想知道。如果你需要了解更多,你也许可以在arm找到一份工作,也许他们会
.thumb
mov r1,r2
mov r10,r2
mov r1,r11
mov r10,r11
    
00000000 <.text>:
   0:   1c11        adds    r1, r2, #0
   2:   4692        mov r10, r2
   4:   4659        mov r1, r11
   6:   46da        mov r10, r11