ARM сборка memcpy эквивалент - PullRequest
       16

ARM сборка memcpy эквивалент

0 голосов
/ 21 декабря 2018

Я смотрю вывод этой функции в сборке:

extern void write(char * buff);

void test(int x)
{
    // copy "EXAMPLE\0\0\0\0\0..."
    char buff[16] = "EXAMPLE";

    // set byte 10 to '0'+x
    buff[10] = '0' + x;

    // write
    write(buff);
}

И выглядит вот так :

test:
        push    {r4, lr}
        ldr     r2, .L4
        mov     r3, r0
        ldm     r2, {r0, r1}
        sub     sp, sp, #16
        mov     r2, sp
        adds    r3, r3, #48
        stm     r2, {r0, r1}
        movs    r4, #0
        mov     r0, r2
        strd    r4, r4, [sp, #8]
        strb    r3, [sp, #10]
        bl      write
        add     sp, sp, #16
        pop     {r4, pc}
.L4:
        .word   .LANCHOR0
        .cfi_endproc
.LFE0:
        .size   test, .-test
        .section        .rodata
        .align  2
        .set    .LANCHOR0,. + 0
        .ascii  "EXAMPLE\000"
        .space  8
        .text

Я совершенно озадачен тем, гдепроисходит копирование из .L4 в стек?

Я вижу, как указатель стека перемещается на 16B, и я вижу инструкцию adds для '0'+x, но какая команда копирует данные?

Извините за вопрос новичка, спасибо!

Ответы [ 2 ]

0 голосов
/ 21 декабря 2018

Сгенерированный код зависит от типа оптимизации: оптимизированный размер:

    push    {r0, r1, r2, r3, r4, lr}
    mov     r2, #8
    ldr     r1, .L3
    mov     r4, r0
    mov     r0, sp
    bl      memcpy
    mov     r3, #0
    add     r4, r4, #48
    mov     r0, sp
    str     r3, [sp, #8]
    str     r3, [sp, #12]
    strb    r4, [sp, #10]
    bl      write
    add     sp, sp, #16
    pop     {r4, pc}

-O3

    str     lr, [sp, #-4]!
    sub     sp, sp, #20
    mov     r2, sp
    mov     ip, #0
    ldr     r1, .L4
    add     r3, r0, #48
    ldm     r1, {r0, r1}
    stm     r2, {r0, r1}
    mov     r0, r2
    str     ip, [sp, #8]
    str     ip, [sp, #12]
    strb    r3, [sp, #10]
    bl      write
    add     sp, sp, #20
    ldr     pc, [sp], #4
0 голосов
/ 21 декабря 2018

Инструкции, выполняющие копирование, чередуются с другими инструкциями.

        ldr     r2, .L4
        ldm     r2, {r0, r1}
        mov     r2, sp
        stm     r2, {r0, r1}
        movs    r4, #0
        strd    r4, r4, [sp, #8]

Поскольку компилятор знает содержимое баффа, он может хранить нули напрямую, а не копировать их.

...