Встроенная сборка с вектором, разбитым флагом оптимизации - PullRequest
0 голосов
/ 13 апреля 2020

Я пытаюсь понять, как векторы работают на уровне сборки и когда я компилирую с g++ -masm=intel a.cpp && ./a.out

#include <vector>
#include <stdio.h>
#include <random>

using namespace std;

class Foo {
public:
    int bar(vector<int>& v, int i) {
        __asm__ __volatile__ (R"(
               lea rax, [rsi + 32]
               mov eax, [rax + rdx * 4]
       ;)");
    }
};

int main() {
    srand (time (NULL));
    vector<int> v = {7, rand(),17,279,29,85};
    for (int i = 0; i < v.size(); i++)
        printf("%0d\n", Foo().bar(v, i));
    return 0;
}

Приведенный выше код будет работать нормально, возвращая мои 6 чисел со случайным числом с индексом 1.

Мне очень приятно, так как я могу видеть содержимое моего массива, который правильно хранится в rsi + 32 (также хранится в rbp + 64), а rdx - это индекс, я умножаю на 4 с 4 байт в одно целое число.

Однако, если я скомпилирую с g++ a.cpp -O2 -masm=intel a.cpp && ./a.out, программа будет зависать (также было 0 раз возвращено 6 раз)

Я знаю, что программа оптимизирована и вместо того, чтобы иметь «Нормальная» программа, с функцией вызывающего и вызываемого, я получаю следующую сборку с godbolt :

main:
        sub     rsp, 40
        xor     edi, edi
        call    time
        mov     rdi, rax
        call    srand
        mov     DWORD PTR [rsp], 7
        call    rand
        mov     edi, 24
        mov     DWORD PTR [rsp+4], eax
        movabs  rax, 1198295875601
        mov     QWORD PTR [rsp+8], rax
        movabs  rax, 365072220189
        mov     QWORD PTR [rsp+16], rax
        call    operator new(unsigned long)
        movdqa  xmm0, XMMWORD PTR [rsp]
        mov     rdx, QWORD PTR [rsp+16]
        movups  XMMWORD PTR [rax], xmm0
        mov     QWORD PTR [rax+16], rdx

               lea rax, [rsi + 32]
               mov eax, [rax + rdx * 4]

И следующую с hexdump -S в as:

    .file   "a.cpp"
    .intel_syntax noprefix
    .text
    .section    .rodata.str1.1,"aMS",@progbits,1
.LC0:
    .string "%0d\n"
    .section    .text.startup,"ax",@progbits
    .p2align 4,,15
    .globl  main
    .type   main, @function
main:
.LFB2455:
    .cfi_startproc
    .cfi_personality 0x9b,DW.ref.__gxx_personality_v0
    .cfi_lsda 0x1b,.LLSDA2455
    push    r12
    .cfi_def_cfa_offset 16
    .cfi_offset 12, -16
    push    rbp
    .cfi_def_cfa_offset 24
    .cfi_offset 6, -24
    xor edi, edi
    push    rbx
    .cfi_def_cfa_offset 32
    .cfi_offset 3, -32
    lea rbp, .LC0[rip]
    mov ebx, 6
    sub rsp, 32
    .cfi_def_cfa_offset 64
    mov rax, QWORD PTR fs:40
    mov QWORD PTR 24[rsp], rax
    xor eax, eax
    call    time@PLT
    mov edi, eax
    call    srand@PLT
    mov DWORD PTR [rsp], 7
    call    rand@PLT
    mov DWORD PTR 4[rsp], eax
    movabs  rax, 1198295875601
    mov edi, 24
    mov QWORD PTR 8[rsp], rax
    movabs  rax, 365072220189
    mov QWORD PTR 16[rsp], rax
.LEHB0:
    call    _Znwm@PLT
.LEHE0:
    movdqa  xmm0, XMMWORD PTR [rsp]
    mov r12, rax
    movups  XMMWORD PTR [rax], xmm0
    mov rax, QWORD PTR 16[rsp]
    mov QWORD PTR 16[r12], rax
    .p2align 4,,10
    .p2align 3
.L2:
#APP
# 13 "a.cpp" 1

               lea rax, [rsi + 32]
               mov eax, [rax + rdx * 4]
       ;
# 0 "" 2
#NO_APP
    xor edx, edx
    mov rsi, rbp
    mov edi, 1
    xor eax, eax
.LEHB1:
    call    __printf_chk@PLT
.LEHE1:
    sub rbx, 1
    jne .L2
    mov rdi, r12
    call    _ZdlPv@PLT
    xor eax, eax
    mov rcx, QWORD PTR 24[rsp]
    xor rcx, QWORD PTR fs:40
    jne .L10
    add rsp, 32
    .cfi_remember_state
    .cfi_def_cfa_offset 32
    pop rbx
    .cfi_def_cfa_offset 24
    pop rbp
    .cfi_def_cfa_offset 16
    pop r12
    .cfi_def_cfa_offset 8
    ret
.L10:
    .cfi_restore_state
    call    __stack_chk_fail@PLT
.L5:
    mov rbx, rax
    mov rdi, r12
    call    _ZdlPv@PLT
    mov rdi, rbx

Я (пока) не могу свободно читать ассемблер, поэтому у меня возникают проблемы с поиском того, как заставить этот встроенный код ассемблера работать с флагом оптимизации. Любая помощь будет принята с благодарностью!

PS: Я уже прочитал эту ссылку , но это не помогает.

...