Есть ли способ, чтобы компилятор не связывался с встроенной сборкой - PullRequest
2 голосов
/ 05 февраля 2020

Итак, у меня есть этот "тупой" смешанный 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, с инструкциями из встроенной сборки (с очевидным разрешением целей перехода).

По сути, я хочу, чтобы эта точная последовательность инструкций была где-то в двоичном файле. Кстати, я кросс-компилирую с g cc, в O0.

Любые намеки на то, что я могу делать неправильно?

Редактировать: Вот итоговая сборка для основной функции:

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 ]

3 голосов
/ 05 февраля 2020

Неправильная разборка. Вы собираете код ARM, а затем разбираете код Thumb. - user253751 7 минут a go

Добавление некоторых опций компиляции (-mcpu = cortex-m4 -mthumb) помогло.

2 голосов
/ 05 февраля 2020

Вы должны ограничить входы / выходы 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"
     );

Вы также можете удалить привязки к конкретным регистрам и вместо этого использовать %0, %1, et c. в вашем ассемблере, чтобы позволить компилятору назначить их, но вышеприведенное должно работать.

...