c - 如何使用 ARM gcc 7.3 生成以下 arm 汇编程序输出?

标签 c assembly arm

myfunction:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
mul r3, r0, r0
mov r0, r3
mla r0, r1, r0, r2
bx  lr

我能够使用以下 C 函数生成除 mov 指令之外的所有内容。

int myfunction(int r0, int r1, int r2, int r3)
{
  r3 = r0*r0;
  r0 = r3;
  r3 = r0;
  return (r1*r3)+r2;
}

如何在汇编代码中指示 r3 设置为 r0 的地址?

最佳答案

unsigned int myfunction(unsigned int a, unsigned int  b, unsigned int c)
{
  return (a*a*b)+c;
}

你的选择将是这样的

00000000 <myfunction>:
   0:   e52db004    push    {r11}       ; (str r11, [sp, #-4]!)
   4:   e28db000    add r11, sp, #0
   8:   e24dd014    sub sp, sp, #20
   c:   e50b0008    str r0, [r11, #-8]
  10:   e50b100c    str r1, [r11, #-12]
  14:   e50b2010    str r2, [r11, #-16]
  18:   e51b3008    ldr r3, [r11, #-8]
  1c:   e51b2008    ldr r2, [r11, #-8]
  20:   e0010392    mul r1, r2, r3
  24:   e51b200c    ldr r2, [r11, #-12]
  28:   e0000291    mul r0, r1, r2
  2c:   e51b3010    ldr r3, [r11, #-16]
  30:   e0803003    add r3, r0, r3
  34:   e1a00003    mov r0, r3
  38:   e28bd000    add sp, r11, #0
  3c:   e49db004    pop {r11}       ; (ldr r11, [sp], #4)
  40:   e12fff1e    bx  lr

或者这个

00000000 <myfunction>:
   0:   e0030090    mul r3, r0, r0
   4:   e0202391    mla r0, r1, r3, r2
   8:   e12fff1e    bx  lr

正如您可能已经想到的那样。

mov 永远不应该被编译器后端考虑,因为它只是浪费一条指令。 r3 进入 mla 无需将其放入 r0 然后执行 mla。不太确定如何让编译器做更多的事情。即使这样也不鼓励它

unsigned int fun ( unsigned int a )
{
    return(a*a);
}
unsigned int myfunction(unsigned int a, unsigned int  b, unsigned int c)
{
  return (fun(a)*b)+c;
}

给予

00000000 <fun>:
   0:   e1a03000    mov r3, r0
   4:   e0000093    mul r0, r3, r0
   8:   e12fff1e    bx  lr

0000000c <myfunction>:
   c:   e0030090    mul r3, r0, r0
  10:   e0202391    mla r0, r1, r3, r2
  14:   e12fff1e    bx  lr

基本上,如果您不进行优化,您将无法实现您所追求的目标。如果你优化那个 mov 不应该在那里,应该很容易优化掉。

虽然编写高级代码以鼓励编译器输出低级代码的某种程度的操作是可能的,但尝试获得这种准确的输出并不是您应该期望能够做到的事情。

除非你使用内联汇编

asm
(
   "mul r3, r0, r0\n"
   "mov r0, r3\n"
   "mla r0, r1, r0, r2\n"
   "bx lr\n"
);

给出你的结果

Disassembly of section .text:

00000000 <.text>:
   0:   e0030090    mul r3, r0, r0
   4:   e1a00003    mov r0, r3
   8:   e0202091    mla r0, r1, r0, r2
   c:   e12fff1e    bx  lr

或真正的汇编

mul r3, r0, r0
mov r0, r3
mla r0, r1, r0, r2
bx lr

并将其提供给 gcc 而不是 (arm-whatever-gcc so.s -o so.o)

Disassembly of section .text:

00000000 <.text>:
   0:   e0030090    mul r3, r0, r0
   4:   e1a00003    mov r0, r3
   8:   e0202091    mla r0, r1, r0, r2
   c:   e12fff1e    bx  lr

所以从技术上讲,您是在命令行上使用 gcc,但 gcc 会进行一些预处理,然后将其提供给 as。

除非你找到一个核心或者 Rd 和 Rs 必须是相同的寄存器然后可以在 gcc 命令行上指定那个核心/错误/任何东西,否则我看不到 mov 发生,也许,只是也许, clang/llvm 将 fun 和 myfunction 分别编译为字节码,然后组合它们,然后优化,然后输出到目标,然后检查它。我希望在优化或输出中将 mov 优化掉,但你可能会走运。

编辑

我犯了一个错误:

unsigned int myfunction(unsigned int a, unsigned int  b, unsigned int c)
{
  return (a*a*b)+c;
}

arm-linux-gnueabi-gcc --version
arm-linux-gnueabi-gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Disassembly of section .text:

00000000 <myfunction>:
   0:   e0030090    mul r3, r0, r0
   4:   e1a00003    mov r0, r3
   8:   e0202091    mla r0, r1, r0, r2
   c:   e12fff1e    bx  lr

但是这个

arm-none-eabi-gcc --version
arm-none-eabi-gcc (GCC) 8.2.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

arm-none-eabi-gcc -O2 -c so.c -o so.o
arm-none-eabi-objdump -D so.o

so.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <myfunction>:
   0:   e0030090    mul r3, r0, r0
   4:   e0202391    mla r0, r1, r3, r2
   8:   e12fff1e    bx  lr

我必须构建一个 7.3 或去找一个。在 5.x.x 和 8.x.x 之间的某个地方,后端发生了变化或者...

请注意,您可能需要在命令行上使用 -mcpu=arm7tdmi 或 -mcpu=arm9tdmi 或 -march=armv4t 或 -march=armv5t,具体取决于编译器内置的默认目标 (cpu/arch)。或者你可能会得到这样的东西

Disassembly of section .text:

00000000 <myfunction>:
   0:   fb00 f000   mul.w   r0, r0, r0
   4:   fb01 2000   mla r0, r1, r0, r2
   8:   4770        bx  lr
   a:   bf00        nop

这个

arm-none-eabi-gcc --version
arm-none-eabi-gcc (GCC) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

产生

Disassembly of section .text:

00000000 <myfunction>:
   0:   e0030090    mul r3, r0, r0
   4:   e0202391    mla r0, r1, r3, r2
   8:   e12fff1e    bx  lr

因此,您可能必须向后工作才能找到它发生更改的版本,源代码更改为导致它的 gcc 并修改 7.3.0 使一些东西不是真正的 7.3.0 但报告为 7.3.0 并输出您的所需的代码。

关于c - 如何使用 ARM gcc 7.3 生成以下 arm 汇编程序输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53660203/

相关文章:

c - 跟踪 C 中数字的连续重复

c - 混合 bool 和 ret 代码是个坏主意吗

assembly - 如何从 ARM 汇编中的位置独立代码 (PIC) 访问数据?

linux - 在 Linux 上创建 .SO 文件,而不使用 PIC(位置无关代码)(x86 32 位)

assembly - BL 指令 ARM - 它是如何工作的

c - 内联汇编: Passing pointers to a function and using it in that function in assembly

gcc - ARM 编译错误,VFP 寄存器由可执行文件使用,而不是目标文件

c - 段错误的位置

c - 无法将元素插入链表

assembly - 有没有办法让 sbcl 打印出 CPU 寄存器的值?