Large Functions Update
This commit is contained in:
@@ -46,6 +46,7 @@ std::string generateAssembly(const CompilerState& state) {
|
||||
result += "extern rand\n";
|
||||
result += "extern srand\n";
|
||||
result += "extern time\n";
|
||||
result += "extern MessageBoxA\n";
|
||||
|
||||
// 2. SEKCJA DATA (Tylko raz!)
|
||||
result += "section .data\n";
|
||||
@@ -97,7 +98,10 @@ std::string generateAssembly(const CompilerState& state) {
|
||||
instr.type == OpType::DIV ||
|
||||
instr.type == OpType::MOD ||
|
||||
instr.type == OpType::LOGIC_AND ||
|
||||
instr.type == OpType::LOGIC_OR);
|
||||
instr.type == OpType::LOGIC_OR ||
|
||||
instr.type == OpType::MSGBOX ||
|
||||
instr.type == OpType::ARRAY_DECLARE ||
|
||||
instr.type == OpType::ARRAY_SET);
|
||||
|
||||
if (isWriteOp && stackMap.find(instr.arg1) == stackMap.end() && instr.arg1 != "RAX") {
|
||||
stackMap[instr.arg1] = currentStack;
|
||||
@@ -107,7 +111,32 @@ std::string generateAssembly(const CompilerState& state) {
|
||||
switch (instr.type) {
|
||||
case OpType::ASSIGN: {
|
||||
std::string src = instr.arg2;
|
||||
if (instr.arg3 == "STRING") {
|
||||
// ODCZYT TABLICY: x = t[i]
|
||||
if (instr.arg3.find("ARRAY_IDX:") == 0) {
|
||||
std::string indexStr = instr.arg3.substr(10); // Pobierz "i"
|
||||
std::string arrName = instr.arg2; // Pobierz "t"
|
||||
std::string dst = getVarLocation(instr.arg1, stackMap);
|
||||
|
||||
int baseOffset = stackMap[arrName];
|
||||
|
||||
// £adujemy indeks do RCX
|
||||
if (isNumber(indexStr)) result += " mov rcx, " + indexStr + "\n";
|
||||
else result += " mov rcx, " + getVarLocation(indexStr, stackMap) + "\n";
|
||||
|
||||
result += " imul rcx, 8\n"; // index * 8
|
||||
|
||||
// Obliczamy adres
|
||||
result += " mov rdx, rbp\n";
|
||||
result += " sub rdx, " + std::to_string(baseOffset) + "\n";
|
||||
result += " sub rdx, rcx\n";
|
||||
|
||||
// Odczytujemy wartoϾ z tablicy do RAX
|
||||
result += " mov rax, [rdx]\n";
|
||||
|
||||
// Zapisujemy do zmiennej docelowej
|
||||
result += " mov " + dst + ", rax\n"; // Lub eax, zale¿y jak masz
|
||||
}
|
||||
else if (instr.arg3 == "STRING") {
|
||||
// Przypisanie stringa: ³adujemy ADRES (LEA)
|
||||
result += " lea rax, [rel " + src + "]\n";
|
||||
std::string dst = getVarLocation(instr.arg1, stackMap);
|
||||
@@ -255,6 +284,76 @@ std::string generateAssembly(const CompilerState& state) {
|
||||
result += " jmp " + instr.arg1 + "\n";
|
||||
break;
|
||||
}
|
||||
case OpType::ARRAY_DECLARE: {
|
||||
std::string name = instr.arg1;
|
||||
int size = std::stoi(instr.arg2);
|
||||
|
||||
// Rezerwujemy miejsce dla ca³ej tablicy
|
||||
// t[0] bêdzie pod aktualnym currentStack
|
||||
stackMap[name] = currentStack;
|
||||
|
||||
// Przesuwamy wskaŸnik stosu o (rozmiar * 8 bajtów)
|
||||
// Zak³adamy, ¿e ka¿dy element to 64-bit (dla bezpieczeñstwa i prostoty assemblera)
|
||||
currentStack += (size * 8);
|
||||
|
||||
// W ASM nie musimy generowaæ ¿adnego kodu! (Miejsce ju¿ jest z sub rsp, 256)
|
||||
// O ile tablica mieœci siê w tych 256 bajtach.
|
||||
// Jeœli chcesz byæ PRO: dodaj na pocz¹tku funkcji "sub rsp, (currentStack + zapas)"
|
||||
break;
|
||||
}
|
||||
case OpType::ARRAY_SET: {
|
||||
std::string arrName = instr.arg1; // t
|
||||
std::string indexStr = instr.arg2; // i
|
||||
std::string valStr = instr.arg3; // val
|
||||
|
||||
// 1. Obliczamy wartoϾ do wpisania
|
||||
if (isNumber(valStr)) {
|
||||
result += " mov rax, " + valStr + "\n";
|
||||
}
|
||||
else {
|
||||
std::string valLoc = getVarLocation(valStr, stackMap);
|
||||
// Jeœli to zmienna ze stosu, to movsxd (rozszerzenie znaku) lub mov
|
||||
result += " mov rax, " + valLoc + "\n"; // Zak³adamy 64-bit (lub eax dla 32)
|
||||
}
|
||||
|
||||
// 2. Obliczamy adres elementu tablicy
|
||||
// Adres = [rbp - offset_bazowy - (index * 8)]
|
||||
// U nas stackMap trzyma offset_bazowy.
|
||||
// Poniewa¿ stos roœnie w DÓ£, a my rezerwowaliœmy w DÓ£:
|
||||
// t[0] -> offset
|
||||
// t[1] -> offset + 8
|
||||
// Czekaj, rbp-8, rbp-16...
|
||||
// Im wiêkszy offset w stackMap, tym ni¿ej w pamiêci.
|
||||
// stackMap["t"] = 8. [rbp-8].
|
||||
// t[1] powinno byæ [rbp-16].
|
||||
// Czyli Wzór: [rbp - (base_offset + index*8)]
|
||||
|
||||
int baseOffset = stackMap[arrName];
|
||||
|
||||
// £adujemy indeks do RCX
|
||||
if (isNumber(indexStr)) {
|
||||
result += " mov rcx, " + indexStr + "\n";
|
||||
}
|
||||
else {
|
||||
std::string idxLoc = getVarLocation(indexStr, stackMap);
|
||||
result += " mov rcx, " + idxLoc + "\n"; // Pobierz indeks ze zmiennej
|
||||
}
|
||||
|
||||
// Obliczamy przesuniêcie bajtowe: index * 8
|
||||
result += " imul rcx, 8\n";
|
||||
|
||||
// Poniewa¿ adres to RBP - (base + index*8) -> RBP - base - index*8
|
||||
// Musimy to sprytnie zmontowaæ.
|
||||
// Obliczmy finalny adres w RDX.
|
||||
|
||||
result += " mov rdx, rbp\n";
|
||||
result += " sub rdx, " + std::to_string(baseOffset) + "\n"; // RDX = adres t[0]
|
||||
result += " sub rdx, rcx\n"; // RDX = adres t[i]
|
||||
|
||||
// Zapisujemy wartoϾ (RAX) pod adres (RDX)
|
||||
result += " mov [rdx], rax\n";
|
||||
break;
|
||||
}
|
||||
case OpType::LABEL: {
|
||||
result += instr.arg1 + ":\n";
|
||||
break;
|
||||
@@ -339,6 +438,45 @@ std::string generateAssembly(const CompilerState& state) {
|
||||
result += " ret\n";
|
||||
break;
|
||||
}
|
||||
case OpType::MSGBOX: {
|
||||
// Konwencja Windows x64:
|
||||
// RCX = HWND (0 = brak okna nadrzêdnego)
|
||||
// RDX = TreϾ (Text)
|
||||
// R8 = Tytu³ (Caption)
|
||||
// R9 = Typ (0 = przycisk OK)
|
||||
|
||||
std::string title = instr.arg1;
|
||||
std::string text = instr.arg2;
|
||||
|
||||
// --- 1. Ustawiamy RDX (TreϾ) ---
|
||||
if (text.find("str_") == 0) {
|
||||
// Jeœli to litera³ (np. str_5), ³adujemy jego adres (LEA)
|
||||
result += " lea rdx, [rel " + text + "]\n";
|
||||
}
|
||||
else {
|
||||
// Jeœli to zmienna, pobieramy jej wartoœæ ze stosu (która jest adresem)
|
||||
std::string loc = getVarLocation(text, stackMap);
|
||||
result += " mov rdx, " + loc + "\n";
|
||||
}
|
||||
|
||||
// --- 2. Ustawiamy R8 (Tytu³) ---
|
||||
if (title.find("str_") == 0) {
|
||||
result += " lea r8, [rel " + title + "]\n";
|
||||
}
|
||||
else {
|
||||
std::string loc = getVarLocation(title, stackMap);
|
||||
result += " mov r8, " + loc + "\n";
|
||||
}
|
||||
|
||||
// --- 3. Pozosta³e argumenty (Sta³e) ---
|
||||
result += " mov rcx, 0\n"; // HWND = NULL
|
||||
result += " mov r9, 0\n"; // MB_OK
|
||||
|
||||
// --- 4. Wywo³anie ---
|
||||
// Stos (shadow space) jest ju¿ przygotowany na pocz¹tku funkcji (sub rsp, 256)
|
||||
result += " call MessageBoxA\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user