Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.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
C 英特尔x86到ARM程序集转换_C_X86_Arm_Intel Syntax - Fatal编程技术网

C 英特尔x86到ARM程序集转换

C 英特尔x86到ARM程序集转换,c,x86,arm,intel-syntax,C,X86,Arm,Intel Syntax,我目前正在学习汇编语言 为此,我尝试将一些x86代码(AT&T语法)转换为ARM汇编(英特尔语法)代码 __asm__("movl $0x0804c000, %eax;"); __asm__("mov R0,#0x0804c000"); 由此,我了解到在x86中,堆结构的块1从0x08040000开始。但当我尝试在arm中执行相同操作时, 我得到以下错误: /tmp/ccfNZp9F.s:174: Error: invalid constant (804c000) after fixup

我目前正在学习汇编语言

为此,我尝试将一些
x86代码(AT&T语法)
转换为ARM汇编
(英特尔语法)
代码

__asm__("movl $0x0804c000, %eax;");

__asm__("mov R0,#0x0804c000");
由此,我了解到在x86中,堆结构的块1从0x08040000开始。但当我尝试在
arm中执行相同操作时,
我得到以下错误:

/tmp/ccfNZp9F.s:174: Error: invalid constant (804c000) after fixup
我假设问题在于ARM只能加载指令

Question 1: Any idea what would be the first chunk in case of ARM processors?


Question 2:
从上一篇文章中,我知道内存间接寻址是如何工作的

下面写的代码片段是否也在做同样的工作

movl (%eax), %ebx

LDR R0,[R1]

我使用的是ARMv7处理器rev 4(v7l)

对问题1的回答

ARM上的MOV指令只有12位可用于立即值,这些位的使用方式是:8位用于值,4位用于指定向右旋转的次数(旋转次数乘以2,以增加范围)

这意味着该指令只能使用有限数量的值。它们是:

  • 0-255
  • 256,260,264,…,1020
  • 102410401056,…,4080
等等。你得到这个错误是因为你的常数不能用8位+旋转来创建。您可以按照以下指令将该值加载到寄存器:

LDR r0, =0x0804c000
请注意,这是一条伪指令。汇编器基本上会将该常量放在代码中的某个地方,并将其作为内存位置加载,并将其偏移到PC(程序计数器)上

对问题2的回答


是的,这些指令是等效的。

通过查看x86来学习arm不是一个好主意,一个是CISC,非常难看,另一个是RISC,更干净。。只需通过查看架构参考手册中的说明集参考来学习ARM。查找mov指令、add指令等

ARM不使用intel语法,而是使用ARM语法

不要通过使用内联汇编来学习,而是编写真正的汇编。首先使用指令集模拟器,而不是硬件

ARM、Mips和其他工具的目标是固定字长。例如,您将如何适应这样一条指令:将某个立即数移动到寄存器,指定寄存器,并将32位立即数全部放入32位?不可能。因此,对于固定长度的指令集,您不能简单地将任何需要的立即数加载到任何寄存器中。你必须仔细阅读该指令集的规则。mips允许16位即时,arm允许8加减,具体取决于arm指令集和指令的风格。mips限制您可以将这16位放入高位或低位,arm允许您根据arm指令集(arm、thumb、thumb2扩展名)的风格将这8位放入32位寄存器的任何位置

与大多数汇编语言一样,您可以通过这样做来解决这个问题

ldr r0,my_value
...
my_value: .word 0x12345678
对于CISC,immediate只是简单地附加到指令上,因此无论是0字节一路还是20字节一路,无论采用哪种方法,它都仍然存在

ARM汇编程序通常还允许您使用以下快捷方式:

ldr r0,=something
...
something:
这表示用某物的地址加载r0,而不是该位置的内容,而是地址(如lea)

但这有助于找到这条捷径

ldr r0,=0x12345678

如果汇编程序支持,它将分配一个内存位置来保存该值,并生成一条ldr r0、[pc,offset]指令来读取该值。如果立即数在mov的规则范围内,那么汇编器可能会将其优化为mov rd,#立即数。

请参阅:以及我在此处标记的所有重复项。ARM仅支持按2的倍数旋转的8位常量。为了支持像您这样的常量,使用语法
ldr r0,=0x804c000
。汇编程序维护一个文本池并将常量放在那里。使用
PC
相对寻址加载常量。使用指令
.ltorg
在汇编程序中转储池。因为ARM是risc,而x86是cisc,而且它们只是不同的指令集,所以只有一小部分x86代码会直接“移植”到一个。每个x86可能需要多条ARM指令(有时反之亦然,一组x86指令需要一条ARM指令)。所有处理器都有类似的功能,如寄存器间接寻址,是的,这两个功能相同。
ARM语法到底是什么?
Intel语法是英特尔手册中为英特尔处理器定义的语法。AT&T语法是AT&T对其汇编程序的偏离。这两者都与x86以外的任何其他处理器无关。将这些术语应用于ARM、MIPS、AVR、6502、PDP11或任何其他处理器都毫无意义。原始供应商指令集参考中定义的语法是供应商语法,供应商通常制作或已经制作了使用相关语法的汇编程序。但是,任何一个编写汇编程序的人都可以在他们认为合适的时候修改语法,因为汇编语言实际上没有标准,机器代码是标准的,不管你怎么做,你怎么做。以gnu汇编程序对汇编语言所做的工作为例,谢谢。当我尝试使用LDR r0时,=0x0804c000。下面是汇编程序消息:
偏移量超出范围
将.ltorg放在加载该值的位置附近。这将把文字池放在那里,这将解决偏移问题。
.ltorg
正是我所描述的。这是一个文字池;汇编程序放置以满足
ldr r0、=0x804c000
请求的常量数据。也许有帮助?或和在gnu汇编程序手册中。只需在偶尔返回的子程序后添加文本
.ltorg
,这就是您需要知道的所有内容。@artlessnoise:谢谢。只有一个问题:如果我想将数据从r0加载到另一个寄存器,我会执行