summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorElias Haugsbakk <[email protected]>2026-09-20 23:02:49 +0200
committerElias Haugsbakk <[email protected]>2026-09-20 23:02:49 +0200
commitc84b76d3848b089cbdd5650b894067fbf6060161 (patch)
tree6f3911f2416725b1e5f6dbb393f542dd8afb5526 /src
parent79fc3dd706b968a9249dfd2db6b5175e4e4a85d4 (diff)
Implement the record interpretation in asm construction and implement variables
Diffstat (limited to 'src')
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGenerator.java9
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instr.java33
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instructions/Alloc.java12
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instructions/Assign.java11
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instructions/Call.java8
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instructions/Instruction.java9
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/Main.java3
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilder.java130
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilderException.java7
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/assembleAndLink/AssemblerAndLinker.java3
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/tokenization/Lexer.java12
-rw-r--r--src/test/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGeneratorTest.java7
-rw-r--r--src/test/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilderTest.java78
13 files changed, 209 insertions, 113 deletions
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGenerator.java b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGenerator.java
index 1c42673..cf50a74 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGenerator.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGenerator.java
@@ -2,6 +2,10 @@ package no.eliashaugsbakk.kompilator.IRGeneration;
import java.util.ArrayList;
import java.util.List;
+import no.eliashaugsbakk.kompilator.IRGeneration.Instructions.Alloc;
+import no.eliashaugsbakk.kompilator.IRGeneration.Instructions.Assign;
+import no.eliashaugsbakk.kompilator.IRGeneration.Instructions.Call;
+import no.eliashaugsbakk.kompilator.IRGeneration.Instructions.Instruction;
import no.eliashaugsbakk.kompilator.parsing.AST;
import no.eliashaugsbakk.kompilator.parsing.node.Program;
import no.eliashaugsbakk.kompilator.parsing.node.expression.Expression;
@@ -15,7 +19,7 @@ import no.eliashaugsbakk.kompilator.parsing.node.statement.Statement;
public class IRGenerator {
private final AST ast;
- private final List<Instr> ir = new ArrayList<>();
+ private final List<Instruction> ir = new ArrayList<>();
private int tempCounter = 0;
@@ -23,12 +27,13 @@ public class IRGenerator {
this.ast = ast;
}
- public List<Instr> generate() {
+ public List<Instruction> generate() {
Program program = (Program) ast.getRoot();
for (Statement stmt : program.statements) {
generateStatement(stmt);
}
+ ir.forEach(IO::println);
return ir;
}
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instr.java b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instr.java
deleted file mode 100644
index 09ed4f6..0000000
--- a/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instr.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package no.eliashaugsbakk.kompilator.IRGeneration;
-
-import java.util.List;
-
-public sealed interface Instr permits Alloc, Assign, Call {
-}
-
-
-// allocate a new variable: set x: string = "Hello"; mut y: string?;
-//
-// Alloc("x", "string", false, "Hello") // Alloc("y", "string", true, "null")
-record Alloc(String name, String type, boolean mutable, String initializer) implements Instr {
- @Override
- public String toString() {
- return "Alloc[name=" + name + ", type=" + type + ", mutable=" + mutable + ", initializer=\"" + initializer + "\"]";
- }
-}
-
-
-// assign a value to a variable: x = "Hello";
-// Assign("x", "Hello")
-record Assign(String name, String value) implements Instr {
- @Override
- public String toString() {
- return "Assign[name=" + name + ", value=\"" + value + "\"]";
- }
-}
-
-
-// call a function: skriv("hello");
-// Call("skriv", ["t1"])
-record Call(String fn, List<String> args) implements Instr {
-}
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instructions/Alloc.java b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instructions/Alloc.java
new file mode 100644
index 0000000..cda3a56
--- /dev/null
+++ b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instructions/Alloc.java
@@ -0,0 +1,12 @@
+package no.eliashaugsbakk.kompilator.IRGeneration.Instructions;
+
+// allocate a new variable: set x: string = "Hello"; mut y: string?;
+//
+// Alloc("x", "string", false, "Hello") // Alloc("y", "string", true, "null")
+public record Alloc(String name, String type, boolean mutable, String initializer) implements Instruction {
+ @Override
+ public String toString() {
+ return "Alloc[name=" + name + ", type=" + type + ", mutable=" + mutable + ", initializer=\"" +
+ initializer + "\"]";
+ }
+}
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instructions/Assign.java b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instructions/Assign.java
new file mode 100644
index 0000000..80a6d9e
--- /dev/null
+++ b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instructions/Assign.java
@@ -0,0 +1,11 @@
+package no.eliashaugsbakk.kompilator.IRGeneration.Instructions;
+
+// assign a value to a variable: x = "Hello";
+// Assign("x", "Hello")
+public record Assign(String name, String value) implements Instruction {
+ @Override
+ public String toString() {
+ return "Assign[name=" + name + ", value=\"" + value + "\"]";
+ }
+}
+
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instructions/Call.java b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instructions/Call.java
new file mode 100644
index 0000000..98f816c
--- /dev/null
+++ b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instructions/Call.java
@@ -0,0 +1,8 @@
+package no.eliashaugsbakk.kompilator.IRGeneration.Instructions;
+
+import java.util.List;
+
+// call a function: skriv("hello");
+// Call("skriv", ["t1"])
+public record Call(String fn, List<String> args) implements Instruction {
+}
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instructions/Instruction.java b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instructions/Instruction.java
new file mode 100644
index 0000000..09796d6
--- /dev/null
+++ b/src/main/java/no/eliashaugsbakk/kompilator/IRGeneration/Instructions/Instruction.java
@@ -0,0 +1,9 @@
+package no.eliashaugsbakk.kompilator.IRGeneration.Instructions;
+
+public sealed interface Instruction permits Alloc, Assign, Call {
+}
+
+
+
+
+
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/Main.java b/src/main/java/no/eliashaugsbakk/kompilator/Main.java
index f59420c..8d6a5cf 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/Main.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/Main.java
@@ -5,6 +5,7 @@ import no.eliashaugsbakk.kompilator.IO.File;
import no.eliashaugsbakk.kompilator.IO.FileReaderWriter;
import no.eliashaugsbakk.kompilator.IO.FileReaderWriterException;
import no.eliashaugsbakk.kompilator.IRGeneration.IRGenerator;
+import no.eliashaugsbakk.kompilator.IRGeneration.Instructions.Instruction;
import no.eliashaugsbakk.kompilator.asmGeneration.AssemblyBuilder;
import no.eliashaugsbakk.kompilator.assembleAndLink.AssemblerAndLinker;
import no.eliashaugsbakk.kompilator.parsing.AST;
@@ -57,7 +58,7 @@ public class Main {
System.exit(1);
}
- List<String> IR = new IRGenerator(ast).generate();
+ List<Instruction> IR = new IRGenerator(ast).generate();
String assembly = new AssemblyBuilder().createAssembly(IR);
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilder.java b/src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilder.java
index c039bcb..275a683 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilder.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilder.java
@@ -3,14 +3,22 @@ package no.eliashaugsbakk.kompilator.asmGeneration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import no.eliashaugsbakk.kompilator.IRGeneration.Instructions.Alloc;
+import no.eliashaugsbakk.kompilator.IRGeneration.Instructions.Assign;
+import no.eliashaugsbakk.kompilator.IRGeneration.Instructions.Call;
+import no.eliashaugsbakk.kompilator.IRGeneration.Instructions.Instruction;
public class AssemblyBuilder {
- Map<String, String> stringVariables = new HashMap<>();
+ Map<String, StringVar> stringVariables = new HashMap<>();
+
+ record StringVar(String value, boolean mutable) {
+ }
StringBuilder finalAssembly;
StringBuilder text;
StringBuilder rodata;
StringBuilder data;
+ StringBuilder bss;
private final static String exit = """
mov rax, 60
@@ -26,66 +34,109 @@ public class AssemblyBuilder {
this.rodata = new StringBuilder("\n.section .rodata\n");
// Global initialized variables, Read - Write
this.data = new StringBuilder("\n.data\n");
+ // Global uninitialized variables, Read - Write
+ this.bss = new StringBuilder("\n.section .bss\n");
}
- public String createAssembly(List<String> IR) {
- for (String line : IR) {
- line = line.trim();
-
- if (line.startsWith("print")) {
- handlePrint(line);
- } else if (line.contains("=")) {
- handleAssignment(line);
+ public String createAssembly(List<Instruction> IR) {
+ for (Instruction inst : IR) {
+ if (inst instanceof Alloc alloc) {
+ handleAlloc(alloc);
+ } else if (inst instanceof Assign assign) {
+ handleAssign(assign);
+ } else if (inst instanceof Call call) {
+ handleCall(call);
}
}
+
this.text.append(exit);
+
this.finalAssembly.append(text);
this.finalAssembly.append(rodata);
this.finalAssembly.append(data);
+ this.finalAssembly.append(bss);
+
return this.finalAssembly.toString();
}
- private void handleAssignment(String line) {
- /* Example IR:
- variable_name: type = data
- str1: string = "Hello world"
- */
- String name = line.substring(0, line.indexOf(":"));
+ private void handleAssign(Assign assign) {
+ String reassignLabel = assign.name() + "_reassign";
+ this.stringVariables.put(assign.name(), new StringVar(assign.value(), true));
- String dataType = line.substring(line.indexOf(":") + 2, line.indexOf("=") - 1);
+ this.rodata.append(String.format("""
+ %s: .ascii "%s"
+ """, reassignLabel, assign.value()));
- String value = line.substring(line.indexOf("=") + 2);
+ this.text.append(String.format("""
+ lea rax, [rip + %s]
+ mov [rip + %s], rax
+ """, reassignLabel, assign.name()));
+ }
- if (dataType.contains("string")) {
- assignString(name, value);
+ private void handleAlloc(Alloc alloc) {
+ this.stringVariables.put(alloc.name(), new StringVar(alloc.initializer(), alloc.mutable()));
+ if (alloc.mutable()) {
+ handleAllocMut(alloc);
} else {
- IO.println("err: Unknown data type: " + dataType);
+ handleAllocRO(alloc);
}
}
- private void assignString(String name, String value) {
- value = value.substring(1, value.length() - 1);
- this.rodata.append(String.format("""
- %s: .ascii "%s"
- """, name, value));
- this.stringVariables.put(name, value);
+ private void handleAllocMut(Alloc alloc) {
+ if (alloc.type() == null) {
+ this.bss.append(String.format("""
+ %s: .skip 8
+ """, alloc.name()));
+ } else if (alloc.type().equals("string")) {
+ String pointer = alloc.name() + "_ptr";
+ this.rodata.append(String.format("""
+ %s: .ascii "%s"
+ """, pointer, alloc.initializer()));
+ this.data.append(String.format("""
+ %s: .quad %s
+ """, alloc.name(), pointer));
+ } else {
+ throw new AssemblyBuilderException("Not a supported type");
+ }
}
- void handlePrint(String line) {
- /* Takes in a print statement and constructs the assembly
- example input:
- print(x)
- */
- String variableName = line.substring(line.indexOf("(") + 1, line.lastIndexOf(")"));
-
- int stringLength = 0;
- try {
- stringLength = this.stringVariables.get(variableName).length();
- } catch (RuntimeException e) {
- IO.println("No variable " + variableName + " initialized in IR.");
+ private void handleAllocRO(Alloc alloc) {
+ if (alloc.type().equals("string")) {
+ this.rodata.append(String.format("""
+ %s: .ascii "%s"
+ """, alloc.name(), alloc.initializer()));
+ } else {
+ throw new AssemblyBuilderException("Not a supported type to skriv");
}
+ }
- this.text.append(String.format("""
+ private void handleCall(Call call) {
+ if (call.fn().equals("skriv")) {
+ handlePrint(call);
+ } else {
+ throw new AssemblyBuilderException("unknown call type: " + call.fn());
+ }
+ }
+
+ void handlePrint(Call call) {
+ if (call.args().size() != 1) {
+ throw new AssemblyBuilderException("Print only supports one argument");
+ }
+ String variableName = call.args().getFirst();
+ StringVar var = this.stringVariables.get(variableName);
+ int stringLength = var.value().length();
+
+ if (var.mutable()) {
+ this.text.append(String.format("""
+ mov rsi, [rip + %s]
+ mov rax, 1
+ mov rdi, 1
+ mov rdx, %d
+ syscall
+
+ """, variableName, stringLength));
+ } else {
+ this.text.append(String.format("""
mov rax, 1
mov rdi, 1
lea rsi, %s
@@ -93,5 +144,6 @@ public class AssemblyBuilder {
syscall
""", variableName, stringLength));
+ }
}
}
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilderException.java b/src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilderException.java
new file mode 100644
index 0000000..f477423
--- /dev/null
+++ b/src/main/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilderException.java
@@ -0,0 +1,7 @@
+package no.eliashaugsbakk.kompilator.asmGeneration;
+
+public class AssemblyBuilderException extends RuntimeException {
+ public AssemblyBuilderException(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/assembleAndLink/AssemblerAndLinker.java b/src/main/java/no/eliashaugsbakk/kompilator/assembleAndLink/AssemblerAndLinker.java
index 5ab0b57..9abbc05 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/assembleAndLink/AssemblerAndLinker.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/assembleAndLink/AssemblerAndLinker.java
@@ -45,6 +45,7 @@ public class AssemblerAndLinker {
}
// Clean up
+ /*
try {
fileReaderWriter.deleteFile(assemblyFileName);
} catch (FileReaderWriterException e) {
@@ -55,6 +56,8 @@ public class AssemblerAndLinker {
} catch (FileReaderWriterException e) {
IO.println("err: Could not delete assembled file: " + e.getMessage());
}
+
+ */
}
private static void runProcess(ProcessBuilder processBuilder)
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/tokenization/Lexer.java b/src/main/java/no/eliashaugsbakk/kompilator/tokenization/Lexer.java
index 9e9ebfd..fb3e09e 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/tokenization/Lexer.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/tokenization/Lexer.java
@@ -125,6 +125,18 @@ public class Lexer {
state = NORMAL;
position++; // skip closing "
current = input.charAt(position);
+ } else if (current == '\\' && position + 1 < input.length()) {
+ // The source file contains \n as two characters: '\' and 'n'.
+ // We intercept the backslash and emit the character it represents.
+ position++;
+ current = input.charAt(position);
+ switch (current) {
+ case 'n' -> wordBuffer.append('\n');
+ case 't' -> wordBuffer.append('\t');
+ case 'r' -> wordBuffer.append('\r');
+ case '\\' -> wordBuffer.append('\\');
+ default -> wordBuffer.append(current);
+ }
} else {
wordBuffer.append(current);
}
diff --git a/src/test/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGeneratorTest.java b/src/test/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGeneratorTest.java
index 232b8f3..844782f 100644
--- a/src/test/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGeneratorTest.java
+++ b/src/test/java/no/eliashaugsbakk/kompilator/IRGeneration/IRGeneratorTest.java
@@ -3,6 +3,9 @@ package no.eliashaugsbakk.kompilator.IRGeneration;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.List;
+import no.eliashaugsbakk.kompilator.IRGeneration.Instructions.Alloc;
+import no.eliashaugsbakk.kompilator.IRGeneration.Instructions.Call;
+import no.eliashaugsbakk.kompilator.IRGeneration.Instructions.Instruction;
import no.eliashaugsbakk.kompilator.parsing.AST;
import no.eliashaugsbakk.kompilator.parsing.node.Program;
import no.eliashaugsbakk.kompilator.parsing.node.expression.FunctionCall;
@@ -15,7 +18,7 @@ class IRGeneratorTest {
@Test
void singlePrintStatementGeneratesCorrectIR() {
AST ast = buildAST("skriv", "hello");
- List<Instr> ir = new IRGenerator(ast).generate();
+ List<Instruction> ir = new IRGenerator(ast).generate();
assertEquals(2, ir.size());
assertEquals(new Alloc("t0", "string", false, "hello"), ir.get(0));
@@ -28,7 +31,7 @@ class IRGeneratorTest {
program.addStatement(buildStatement("skriv", "hello"));
program.addStatement(buildStatement("skriv", "world"));
- List<Instr> ir = new IRGenerator(new AST(program)).generate();
+ List<Instruction> ir = new IRGenerator(new AST(program)).generate();
assertEquals(4, ir.size());
assertEquals(new Alloc("t0", "string", false, "hello"), ir.get(0));
diff --git a/src/test/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilderTest.java b/src/test/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilderTest.java
index 4c124fc..9707ef3 100644
--- a/src/test/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilderTest.java
+++ b/src/test/java/no/eliashaugsbakk/kompilator/asmGeneration/AssemblyBuilderTest.java
@@ -1,65 +1,71 @@
package no.eliashaugsbakk.kompilator.asmGeneration;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
import java.util.List;
+import no.eliashaugsbakk.kompilator.IRGeneration.Instructions.Call;
import org.junit.jupiter.api.Test;
class AssemblyBuilderTest {
@Test
void boilerplateGetsGenerated() {
- // Setup
AssemblyBuilder builder = new AssemblyBuilder();
- // Act
-
- // Assert
String result = builder.createAssembly(List.of());
- assert result.contains("""
- .intel_syntax noprefix
- .global _start
- .text
- _start:
- """);
-
- assert result.contains("""
- mov rax, 60
- xor rdi, rdi
- syscall
- """);
- assert result.contains(".data");
+
+ assertTrue(result.contains(".intel_syntax noprefix\n.global _start"));
+ assertTrue(result.contains("mov rax, 60\nxor rdi, rdi\nsyscall"));
+ assertTrue(result.contains(".data"));
+ }
+
+ @Test
+ void handlePrintGeneratesCorrectAssemblyForImmutableVariable() {
+ AssemblyBuilder builder = new AssemblyBuilder();
+ builder.stringVariables.put("greeting", new AssemblyBuilder.StringVar("Hello", false));
+
+ builder.handlePrint(new Call("skriv", List.of("greeting")));
+
+ String result = builder.text.toString();
+ assertTrue(result.contains("lea rsi, greeting"));
+ assertTrue(result.contains("mov rdx, 5"));
}
@Test
- void handlePrintGeneratesCorrectAssemblyForSingleStatement() {
- // Setup
+ void handlePrintGeneratesCorrectAssemblyForMutableVariable() {
AssemblyBuilder builder = new AssemblyBuilder();
- builder.stringVariables.put("greeting", "Hello");
+ builder.stringVariables.put("greeting", new AssemblyBuilder.StringVar("Hello", true));
- // Act
- builder.handlePrint("skriv(greeting)");
+ builder.handlePrint(new Call("skriv", List.of("greeting")));
- // Assert
String result = builder.text.toString();
- assert result.contains("lea rsi, greeting");
- assert result.contains("mov rdx, 5"); // "Hello"
+ assertTrue(result.contains("mov rsi, [rip + greeting]"));
+ assertTrue(result.contains("mov rdx, 5"));
+ }
+
+ @Test
+ void handlePrintCorrectlyCountsNewlineAsOneByte() {
+ AssemblyBuilder builder = new AssemblyBuilder();
+ builder.stringVariables.put("msg", new AssemblyBuilder.StringVar("Hello\n", false));
+
+ builder.handlePrint(new Call("skriv", List.of("msg")));
+
+ assertTrue(builder.text.toString().contains("mov rdx, 6"));
}
@Test
void handlePrintWorksCorrectlyWithMultiplePrintStatements() {
- // Setup
AssemblyBuilder builder = new AssemblyBuilder();
- builder.stringVariables.put("msg1", "Hi");
- builder.stringVariables.put("msg2", "World");
+ builder.stringVariables.put("msg1", new AssemblyBuilder.StringVar("Hi", false));
+ builder.stringVariables.put("msg2", new AssemblyBuilder.StringVar("World", false));
- // Act
- builder.handlePrint("skriv(msg1)");
- builder.handlePrint("skriv(msg2)");
+ builder.handlePrint(new Call("skriv", List.of("msg1")));
+ builder.handlePrint(new Call("skriv", List.of("msg2")));
- // Assert
String result = builder.text.toString();
- assert (result).contains("lea rsi, msg1");
- assert (result).contains("lea rsi, msg2");
- assert (result).contains("mov rdx, 2"); // "Hi"
- assert (result).contains("mov rdx, 5"); // "World"
+ assertTrue(result.contains("lea rsi, msg1"));
+ assertTrue(result.contains("lea rsi, msg2"));
+ assertTrue(result.contains("mov rdx, 2"));
+ assertTrue(result.contains("mov rdx, 5"));
}
}