g++ kod asm z cpp - pomoc w interpretacji

0

Z następującego kodu:

class KlasaMoja {
    public:
            KlasaMoja(): x{123} {}
    private:
            int x;
};

int main() {
    KlasaMoja x;
    return 1;
}

poleceniem : g++ -S -fno-stack-protector asd.cpp

otrzymałem kod:

        .file   "asd.cpp"
        .text
        .section        .text._ZN9KlasaMojaC2Ev,"axG",@progbits,_ZN9KlasaMojaC5Ev,comdat
        .align 2
        .weak   _ZN9KlasaMojaC2Ev
        .type   _ZN9KlasaMojaC2Ev, @function
_ZN9KlasaMojaC2Ev:
.LFB1:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        movq    %rdi, -8(%rbp)
        movq    -8(%rbp), %rax
        movl    $123, (%rax)
        nop
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE1:
        .size   _ZN9KlasaMojaC2Ev, .-_ZN9KlasaMojaC2Ev
        .weak   _ZN9KlasaMojaC1Ev
        .set    _ZN9KlasaMojaC1Ev,_ZN9KlasaMojaC2Ev
        .text
        .globl  main
        .type   main, @function
main:
.LFB3:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        subq    $16, %rsp
        leaq    -4(%rbp), %rax
        movq    %rax, %rdi
        call    _ZN9KlasaMojaC1Ev
        movl    $1, %eax
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE3:
        .size   main, .-main
        .ident  "GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0"
        .section        .note.GNU-stack,"",@progbits

Z kodu asm zakładam, że istotne są main i .LFB1, reszta to metadane, które będę pomijał, proszę o weryfikację czy dobrze rozumiem co się tutaj zadziało w razie czego bardzo proszę o korektę.

#############################################################################
Linia 33, 36 - prolog maina

200: [RIP] -> zapamietanie gdzie skoczyc po skonczeniu maina
**192: ** [RBP ramki maina] <- RSP, RBP

#############################################################################
Linia 38:
200: [RIP] -> zapamietanie gdzie skoczyc po skonczeniu maina
**192: ** [RBP ramki maina] <- RBP
**184: ** [smieci]
**176: ** [smieci] <- RSP

#############################################################################
Linia 39:

Zapisanie do rejestru RAX wskaznika na adres 192 - 4 czyli 188 (od adresu na ktory wskazuje RBP odejmujemy 4 bajty)

200: [RIP] -> zapamietanie gdzie skoczyc po skonczeniu maina
**192: ** [RBP ramki maina] <- RBP
**188: ** <- RAX
**184: ** [smieci]
**176: ** [smieci] <- RSP

#############################################################################
Linia 40:

Zapisanie wskaznika z RAX do RDI

200: [RIP] -> zapamietanie gdzie skoczyc po skonczeniu maina
**192: ** [RBP ramki maina] <- RBP
**188: ** <- RAX, RDI
**184: ** [smieci]
**176: ** [smieci] <- RSP

#############################################################################
Linia 41:

Wywołanie kontruktora MojaKlasa

200: [RIP] -> zapamietanie gdzie skoczyc po skonczeniu maina
**192: ** [RBP ramki maina] <- RBP
**188: ** <- RAX, RDI
**184: ** [smieci]
**176: ** [smieci]
**168: ** [RIP] <- RSP, zapamietanie gdzie wrocic do maina

#############################################################################
Linia 10:
200: [RIP] -> zapamietanie gdzie skoczyc po skonczeniu maina
**192: ** [RBP ramki maina] <- RBP
**188: ** <- RAX, RDI
**184: ** [smieci]
**176: ** [smieci]
**168: ** [RIP] <- zapamietanie gdzie wrocic do maina
**160: ** [RBP ramka konstruktora MojejKlasy] <- RSP

#############################################################################
Linia 13:

200: [RIP] -> zapamietanie gdzie skoczyc po skonczeniu maina
**192: ** [RBP ramki maina]
**188: ** <- RAX, RDI
**184: ** [smieci]
**176: ** [smieci]
**168: ** [RIP] <- zapamietanie gdzie wrocic do maina
**160: ** [RBP ramka konstruktora MojejKlasy] <- RBP, ESP

#############################################################################
Linia 15:

200: [RIP] -> zapamietanie gdzie skoczyc po skonczeniu maina
**192: ** [RBP ramki maina]
**188: ** <- RAX, RDI
**184: ** [smieci]
**176: ** [smieci]
**168: ** [RIP] <- zapamietanie gdzie wrocic do maina
**160: ** [RBP ramka konstruktora MojejKlasy] <- RBP, ESP
**152: ** [RBP-8], wskazuje na 188 (tam gdzie RDI)

#############################################################################
Linia 16:

200: [RIP] -> zapamietanie gdzie skoczyc po skonczeniu maina
**192: ** [RBP ramki maina]
**188: ** <- RAX, RDI
**184: ** [smieci]
**176: ** [smieci]
**168: ** [RIP] <- zapamietanie gdzie wrocic do maina
**160: ** [RBP ramka konstruktora MojejKlasy] <- RBP, ESP
**152: ** [RBP-8], wskazuje na 188 (tam gdzie RDI)

RAX teraz na pewno wskazuje na 188 (pytanie czy gdzies po drodze zmienilo to na co wskazywalo ze tutaj jest to ponowne przypisanie ?!

#############################################################################
Linia 17:

200: [RIP] -> zapamietanie gdzie skoczyc po skonczeniu maina
**192: ** [RBP ramki maina]
**188: ** [123] <- RAX, RDI
**184: ** [smieci]
**176: ** [smieci]
**168: ** [RIP] <- zapamietanie gdzie wrocic do maina
**160: ** [RBP ramka konstruktora MojejKlasy] <- RBP, ESP
**152: ** [RBP-8], wskazuje na 188 (tam gdzie RDI)

Zapisanie 123 pod adres 188

#############################################################################
Linia 18:
po co nop ?

#############################################################################
Linia 19:

200: [RIP] -> zapamietanie gdzie skoczyc po skonczeniu maina
**192: ** [RBP ramki maina] <- RBP
**188: ** [123] <- RAX, RDI
**184: ** [smieci]
**176: ** [smieci]
**168: ** [RIP] <- zapamietanie gdzie wrocic do maina <- ESP
**160: ** [RBP ramka konstruktora MojejKlasy]
**152: ** [RBP-8], wskazuje na 188 (tam gdzie RDI)

#############################################################################
Linia 21:

200: [RIP] -> zapamietanie gdzie skoczyc po skonczeniu maina
**192: ** [RBP ramki maina] <- RBP
**188: ** [123] <- RAX, RDI
**184: ** [smieci] <- RSP

Powrót do maina (ze stosu zdjeto, adres powrotu do maina + wskaznik do MojaKlasa (czyli instrukcja + wskaznik = 8 + 8 = 16 bajtow) RSP = 168 + 16=184

Od 42 lini juz wracamy do os.

Pytania mam 2:

  1. czy Ten opis jest poprawny, jezeli nie to gdzie się pomyliłem
  2. Dlaczego w lini 15/16 są takie "cuda" robione:
         movq    %rdi, -8(%rbp)
        movq    -8(%rbp), %rax

przeciez RDI i RAX wskazuja to miejsce i mozna z nich te wartosc wziac ? Dodatkowo pytanie czy tam nie operuje przypadkiem ponizej adresow wskazywanych przez RSP ? czy to bezpieczne (pewnie tak) ? Będę bardzo wdzięczny wszystkim osob, które poświęcom czas by to przeanalizować i mi pomóc

3

FYI: tu jest taki fajny tool do analizowania takich rzeczy:
https://godbolt.org/z/qvhvfdGcK

Bez w włączonych optymalizacji generowany kod ma prawo zawierać rzeczy, które robią coś bezsensu.
Włącznie optymalizacji powoduje, że wszystko co kompilator potrafi ustalić, że nie ma widocznych skutków, zostanie usunięte (w twoim wypadku wszystko https://godbolt.org/z/MTT1qPGT3).

1 użytkowników online, w tym zalogowanych: 0, gości: 1