首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将我的C++程序转换为ARM程序集

将我的C++程序转换为ARM程序集
EN

Stack Overflow用户
提问于 2022-03-27 23:49:31
回答 2查看 937关注 0票数 1

我已被指派将此程序转换为arm汇编v8。

代码语言:javascript
运行
复制
int power(int x, int y){
    if (x == 0){
        return 0;
    }
    else if (y < 0){
        return 0;
    }
    else if (y == 0){
        return 1;
        
    }
    else {
        return x * power(x, y - 1);
    }
}

虽然我不太熟悉ARM汇编语言,并想知道从哪里开始。

我曾尝试过对此进行一些研究,但最终在互联网上很少发现有关ARM的信息。

EN

回答 2

Stack Overflow用户

发布于 2022-03-28 00:07:33

神奇的命令是arm-linux-gnueabi-gcc -S -O2 -march=armv8-a power.c

  • 我使用arm-linux-gnueabi-gcc,因为我在X86-64机器上工作,而gcc没有可用的ARM目标。如果您使用的是arm系统,则应该能够使用常规的gcc。如果没有,就会出错,但不会造成伤害。
  • -S告诉gcc输出程序集。
  • -O2是可选的,只有助于稍微优化代码,并减少结果中的调试杂乱。
  • -march=armv8-a告诉它在编译时使用ARM v8目标。我有点武断地选择了armv8-a。根据这些文档,所有的ARM v8都是armv8-aarmv8.1-aarmv8.2-aarmv8.3-aarmv8.4-aarmv8.5-aarmv8.6-aarmv8-m.basearmv8-m.mainarmv8.1-m.main。我不知道有什么不同,所以你可以选择另一个。
  • power.c只是告诉它要编译哪个文件。因为我们没有指定输出文件(Ex:-o output.asm),所以程序集将输出到power.s

如果没有在提供常规arm目标的gcc机器上进行编译,则可以使用arm-linux-gnueabi-gcc。如果您没有安装它,您可以用以下方式安装它:

代码语言:javascript
运行
复制
sudo apt-get update
sudo apt-get install gcc-arm-linux-gnueabi binutils-arm-linux-gnueabi

输出

如果有人好奇的话,这就是我在我的机器上试用时收到的输出。

代码语言:javascript
运行
复制
        .arch armv8-a
        .eabi_attribute 20, 1
        .eabi_attribute 21, 1
        .eabi_attribute 23, 3
        .eabi_attribute 24, 1
        .eabi_attribute 25, 1
        .eabi_attribute 26, 2
        .eabi_attribute 30, 2
        .eabi_attribute 34, 1
        .eabi_attribute 18, 4
        .file   "testing.c"
        .text
        .align  2
        .global power
        .syntax unified
        .arm
        .fpu softvfp
        .type   power, %function
power:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        clz     r2, r0
        mov     r3, r0
        lsr     r2, r2, #5
        orrs    r2, r2, r1, lsr #31
        bne     .L4
        cmp     r1, #0
        mov     r0, #1
        bxeq    lr
.L3:
        subs    r1, r1, #1
        mul     r0, r3, r0
        bne     .L3
        bx      lr
.L4:
        mov     r0, #0
        bx      lr
        .size   power, .-power
        .ident  "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0"
        .section        .note.GNU-stack,"",%progbits

我怎么才能开始。

这是我如何解决这个问题的思考过程。看一下这个问题,我可以看出它可能分为两部分:

  1. 如何将该代码编译成程序集? 对于第一部分,我找到了这个答案,它提供了gcc -S -fverbose-asm -O2 foo.c命令。经过测试,我决定删除-fverbose-asm,因为它似乎只为这么小的程序提供了混乱。
  2. 如何将编译器目标设置为ARM v8? 在google快速搜索之后,我发现gcc允许您使用-march=xxx指定目标体系结构。我的下一步是找到一个ARM架构列表,我可以从中选择。在找到gcc.gnu.org/onlinedocs/gcc/ARM-Options.html之后,我选择了armv8-a,因为它听起来最正确。当我尝试时,gcc告诉我,无法找到目标体系结构。这并不令人惊讶,因为我在x86-64上,编译器通常会附带兼容的目标,以减少所需的空间。我知道这可能意味着我需要识别提供arm目标的apt包,所以我四处搜索,直到找到了这个答案,它填充了我需要的其余信息。
票数 1
EN

Stack Overflow用户

发布于 2022-03-28 00:19:24

在这样一个简单的例子中,编译器资源管理器就是朋友。

ARMv8 8-具有编译器选项-O1的Clang程序集,用于保持递归:

代码语言:javascript
运行
复制
# Compilation provided by Compiler Explorer at https://godbolt.org/
power(int, int):                             // @power(int, int)
        stp     x29, x30, [sp, #-32]!           // 16-byte Folded Spill
        str     x19, [sp, #16]                  // 8-byte Folded Spill
        mov     x29, sp
        mov     w19, w0
        mov     w0, wzr
        cbz     w19, .LBB0_5
        tbnz    w1, #31, .LBB0_5
        cbz     w1, .LBB0_4
        sub     w1, w1, #1
        mov     w0, w19
        bl      power(int, int)
        mul     w0, w0, w19
        b       .LBB0_5
.LBB0_4:
        mov     w0, #1
.LBB0_5:
        ldr     x19, [sp, #16]                  // 8-byte Folded Reload
        ldp     x29, x30, [sp], #32             // 16-byte Folded Reload
        ret

ARM GCC (linux)程序集具有编译器选项-O1,用于保持递归:

代码语言:javascript
运行
复制
# Compilation provided by Compiler Explorer at https://godbolt.org/
power(int, int):
        push    {r4, lr}
        mov     r4, r0
        clz     r0, r0
        lsrs    r0, r0, #5
        orrs    r3, r0, r1, lsr #31
        it      ne
        movne   r0, #0
        beq     .L6
.L1:
        pop     {r4, pc}
.L6:
        movs    r0, #1
        cmp     r1, #0
        beq     .L1
        subs    r1, r1, #1
        mov     r0, r4
        bl      power(int, int)
        mul     r0, r4, r0
        b       .L1

ARM GCC (无)装配与编译器选项-O1保持递归:

代码语言:javascript
运行
复制
# Compilation provided by Compiler Explorer at https://godbolt.org/
power(int, int):
        push    {r4, lr}
        mov     r4, r0
        rsbs    r0, r0, #1
        movcc   r0, #0
        orrs    r3, r0, r1, lsr #31
        movne   r0, #0
        beq     .L6
.L1:
        pop     {r4, lr}
        bx      lr
.L6:
        cmp     r1, #0
        moveq   r0, #1
        beq     .L1
        sub     r1, r1, #1
        mov     r0, r4
        bl      power(int, int)
        mul     r0, r4, r0
        b       .L1

ARM64 GCC程序集具有编译器选项-O1,用于保持递归:

代码语言:javascript
运行
复制
# Compilation provided by Compiler Explorer at https://godbolt.org/
power(int, int):
        cmp     w1, 0
        ccmp    w0, 0, 4, ge
        bne     .L9
        mov     w0, 0
        ret
.L9:
        stp     x29, x30, [sp, -32]!
        mov     x29, sp
        str     x19, [sp, 16]
        mov     w19, w0
        mov     w0, 1
        cbnz    w1, .L10
.L1:
        ldr     x19, [sp, 16]
        ldp     x29, x30, [sp], 32
        ret
.L10:
        sub     w1, w1, #1
        mov     w0, w19
        bl      power(int, int)
        mul     w0, w19, w0
        b       .L1
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71641153

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档