有没有一种方法可以防止编译器弄乱内联汇编

时间:2020-02-05 14:48:10

标签: c arm inline-assembly

所以我有这段“哑巴”的混合C代码和ARM汇编

int main(int argc, char ** argv)
{
    register int val asm("r0");
    register volatile int dummy asm("r2");
    register int res asm("r3");
    val = atoi(argv[1]);
    res = 0xfffffff;
    dummy = 0xffffffff;
    asm volatile(
         "cmp   r0,    #0   \n"
         "beq   edest       \n" 
         "movs  r2,    #0   \n"
         "b     fdest       \n"
 "edest : movs  r2,    #2   \n"
 "fdest : add   r3,    r2   \n"
     : 
     : 
     : "r0", "r2", "r3", "cc"
     );

    return res;
}

而且我找不到防止编译器弄乱它的方法。 我说“与它聊天”的意思是: -使用任何其他寄存器。 -将C代码的编译生成的指令与内联汇编的指令相交织(明显解决了跳转目标)。

基本上,我想在二进制文件中的某处具有此确切的指令序列。 顺便说一下,我在O0与gcc进行交叉编译。

有什么暗示我可能做错了吗?

编辑: 这是主要功能的组装结果:

00008244 <main>:
    8244:   4800        ldr r0, [pc, #0]    ; (8248 <main+0x4>)
    8246:   e92d b004   stmdb   sp!, {r2, ip, sp, pc}
    824a:   e28d        b.n 8768 <__call_exitprocs+0x20>
    824c:   d008        beq.n   8260 <main+0x1c>
    824e:   e24d        b.n 86ec <strtol_l+0x28>
    8250:   0008        movs    r0, r1
    8252:   e50b        b.n 7c6c <_init-0x394>
    8254:   100c        asrs    r4, r1, #32
    8256:   e50b        b.n 7c70 <_init-0x390>
    8258:   300c        adds    r0, #12
    825a:   e51b        b.n 7c94 <_init-0x36c>
    825c:   3004        adds    r0, #4
    825e:   e283        b.n 8768 <__call_exitprocs+0x20>
    8260:   3000        adds    r0, #0
    8262:   e593        b.n 7d8c <_init-0x274>
    8264:   0003        movs    r3, r0
    8266:   e1a0        b.n 85aa <_strtol_l.isra.0+0x142>
    8268:   000d        movs    r5, r1
    826a:   eb00 3000   add.w   r0, r0, r0, lsl #12
    826e:   e1a0        b.n 85b2 <_strtol_l.isra.0+0x14a>
    8270:   0003        movs    r3, r0
    8272:   e1a0        b.n 85b6 <_strtol_l.isra.0+0x14e>
    8274:   320f        adds    r2, #15
    8276:   e3e0        b.n 8a3a <__retarget_lock_try_acquire_recursive+0x6>
    8278:   2000        movs    r0, #0
    827a:   e3e0        b.n 8a3e <__retarget_lock_release+0x2>
    827c:   0000        movs    r0, r0
    827e:   e350        b.n 8922 <__libc_fini_array+0x2e>
    8280:   0001        movs    r1, r0
    8282:   0a00        lsrs    r0, r0, #8
    8284:   2000        movs    r0, #0
    8286:   e3b0        b.n 89ea <__locale_ctype_ptr+0x16>
    8288:   0000        movs    r0, r0
    828a:   ea00 2002   and.w   r0, r0, r2, lsl #8

0000828c <edest>:
    828c:   2002        movs    r0, #2
    828e:   e3b0        b.n 89f2 <__locale_ctype_ptr+0x1e>

00008290 <fdest>:
    8290:   3002        adds    r0, #2
    8292:   e083        b.n 839c <memset+0x48>
    8294:   0003        movs    r3, r0
    8296:   e1a0        b.n 85da <_strtol_l.isra.0+0x172>
    8298:   d004        beq.n   82a4 <atoi>
    829a:   e24b        b.n 8734 <strtol+0x38>
    829c:   4800        ldr r0, [pc, #0]    ; (82a0 <fdest+0x10>)
    829e:   e8bd ff1e   ldmia.w sp!, {r1, r2, r3, r4, r8, r9, sl, fp, ip, sp, lr, pc}
    82a2:   e12f        b.n 8504 <_strtol_l.isra.0+0x9c>

它是如此混乱,很难将原始内联汇编与最终说明相匹配

2 个答案:

答案 0 :(得分:3)

反汇编是错误的。您要汇编ARM代码,然后反汇编Thumb代码。 – user253751 7分钟前

添加一些编译(-mcpu = cortex-m4 -mthumb)选项可以解决问题。

答案 1 :(得分:2)

您必须限制asm输入/输出:

    asm volatile(
         "cmp   r0,    #0   \n"
         "beq   edest       \n" 
         "movs  r2,    #0   \n"
         "b     fdest       \n"
 "edest : movs  r2,    #2   \n"
 "fdest : add   r3,    r2   \n"
     : "+r"(val), "+r"(dummy), "+r"(res)
     : 
     : "cc"
     );

您还可以删除与特定寄存器的绑定,而在您的asm中使用%0%1等让编译器为其分配它们,但是以上方法应该可以工作。