Próba implementacji kompilatora JIT - wstawka Assemblera

0

Witajcie

Próbuję napisać kompilator JIT do interpretera brainfucka. Podpatruję koncepcji w tym filmiku od @Gynvael Coldwind - .

Chciałbym się Was zapytać o jedną rzecz. Mianowicie mam taki kod struktury:

struct bf_state
{
	int index;
	size_t memory_size;	 
	uint8_t *memory_segment; 
};

Jestem w trakcie tworzenia prostego programu w języku assembly, który zrealizowałby choć jedną (na razie w ramach testów) instrukcję brainfucka. Napisałem coś takiego (w oparciu o treść powyższego filmiku oczywiście):

prolog:
    mov eax, [esp+4]    ; adres struktury
    push ecx
    push edx
    mov ecx, [eax+0]    ; index
    mov edx, [eax+8]    ; memory_segment
    add eax, 8           ; przesuniecie pointera w eax na koniec struktury
 
epilog:
    mov eax, [esp+8]    ; adres struktury znow w eax
    mov [eax+0], ecx    ; przenies zaktualizowany index do struktury
    mov [eax+8], edx       ; przenies zaktualizowany memory_segment
    pop edx
    pop ecx
    ret

A tutaj wersja z komentarzami opisującymi zachowanie się rejestru esp (czyli jak ja to rozumiem):

; esp --> [RET]
; [RET] esp --> [ARG1]
prolog:
    mov eax, [esp+4]
        ; [RET] esp --> [ARG1]
    push ecx
        ; [RET] [ARG1] esp --> [ARG2]
    push edx
        ; [RET] [ARG1] [ARG2] esp --> [ARG3]
    mov ecx, [eax+0]    
    mov edx, [eax+8]
    add eax, 8      
 
epilog:
        ; [RET] [ARG1] [ARG2] esp --> [ARG3]
    mov eax, [esp+8]
        ; eax --> [ARG1]
    mov [eax+0], ecx    
    mov [eax+8], edx
    pop edx
    pop ecx
    ret

Chodzi o to, że autor nagrania ma strukturę z taką samą ilością elementów co ja, a w swoim kodzie w "funkcji" epilog ma taką pierwszą instrukcję:

mov eax, [esp+4+8]

Przy czym:
[ARG1] --> adres struktury
[ARG2] --> (*adres struktury).index
[ARG3] --> (*adres struktury).memory_segment

Czy jest ktoś w stanie mi pomóc gdzie popełniłem błąd w analizie? Byłbym bardzo wdzięczny. :)

0

Ale może podaj jakąś minutę z tego filmu bo jest długi...

0

Co do minuty filmu to jest to około 56-57 minuta.

W każdym razie udało mi się rozwiązać ten problem. Po prostu źle zrozumiałem umiejscowienie argumentów na stosie. Myślałem, że stos wygląda tak:

RET
-------------------------------------------
ADRES STRUKTURY
-------------------------------------------
ADRES STRUKTURY->INDEX
-------------------------------------------
ADRES STRUKTURY->MEMORY_SEGMENT    <-- ESP
-------------------------------------------

A tak naprawdę to powinien wyglądać on tak:

ADRES STRUKTURY
-------------------------------------------
RET
-------------------------------------------
ADRES STRUKTURY->INDEX
-------------------------------------------
ADRES STRUKTURY->MEMORY_SEGMENT    <-- ESP
-------------------------------------------

Ponieważ idea jest taka, że adres struktury jest przekazywany do funkcji "jitującej" jako argument. Argument trafia więc na stos przed adresem powrotu funkcji. Wskutek takiego rozstawienia adresów i adresów+offsetów rzeczywiście poprawnym zapisem jest:

mov eax, [esp+4+8]

Wówczas do rejestru eax trafi pożądany adres struktury i względem tego rejestru będę mógł działać na strukturze również w epilogu.

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