ARM 汇编中 switch 语句的实现似乎太少了

问题描述 投票:0回答:1

我正在学习 switch 语句在 C 中如何工作,所以我决定查看编译后的代码。据我了解,C 使用跳转表来实现 switch 语句。但是,我在汇编代码中没有看到任何标签或跳转指令。

我用的是苹果芯片,所以是ARM组装的。请看一下并告诉我您的想法。谢谢:)

C代码:

int main (int argc, char *argv[]) {
    int one;
    int two;
    int three;
    int four;
    
    switch (1) {
        case 1:
            one = 1; 
            break;
        case 2:
            two = 2; 
            break;
        case 3:
            three = 3;
            break;
        default:
            four = 4;
            break;
    }
    
    return 0;
    
}

ARM代码:

    .section    __TEXT,__text,regular,pure_instructions
    .build_version macos, 14, 0 sdk_version 14, 4
    .globl  _main                           ; -- Begin function main
    .p2align    2
_main:                                  ; @main
    .cfi_startproc
; %bb.0:
    sub sp, sp, #32
    .cfi_def_cfa_offset 32
    mov x8, x0
    mov w0, #0
    str wzr, [sp, #28]
    str w8, [sp, #24]
    str x1, [sp, #16]
    mov w8, #1
    str w8, [sp, #12]
    add sp, sp, #32
    ret
    .cfi_endproc
                                        ; -- End function
.subsections_via_symbols
c assembly arm switch-statement
1个回答
0
投票

C 编译器可以根据所谓的 as-if 规则 自由地转换程序。这意味着通过充分的优化,OP 程序可以减少到仅返回 0

为了避免此类优化,常见的方法是设置变量

volatile
。这样就可以看到OP代码的完整翻译了:

sub sp, sp, #24 movs r3, #1 str r3, [sp, #20] ldr r3, [sp, #20] cmp r3, #2 it eq streq r3, [sp, #8] beq .L5 cmp r3, #3 it eq streq r3, [sp, #12] beq .L5 cmp r3, #1 itee eq streq r3, [sp, #4] movne r3, #4 strne r3, [sp, #16] .L5: movs r0, #0 add sp, sp, #24 bx lr
因此,在这种情况下,编译器仍然会进行一系列比较,大概是因为这比查找表更有效。

可能,如果有更多情况,它将使用查找表,但无论如何,现代编译器将竭尽全力制作最高效的代码,以便我们可以专注于编写最可读的代码。

© www.soinside.com 2019 - 2024. All rights reserved.