-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsb.c
More file actions
144 lines (101 loc) · 5.2 KB
/
Copy pathsb.c
File metadata and controls
144 lines (101 loc) · 5.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Assembly templates (Intel syntax)
// Updated header template for modern GCC/Gentoo systems
#define ASM_START ".intel_syntax noprefix\n" \
".global main\n" \
".text\n" \
"main:\n" \
" .type main, @function\n"
#define ASM_EXIT ".section .note.GNU-stack,\"\",@progbits\n"
int main(int argc, char *argv[]) {
if (argv[1] == NULL) {
printf("Usage: smallbasic <input_file>\n");
return 1;
}
FILE *source_code = fopen(argv[1], "r");
FILE *output_asm = fopen("output.s", "w");
// Buffer to dynamicly store the .data section strings at the end of the file
char data_section[4096] = ".data\n";
int text_count = 0;
// Add a format string for printing integers via printf
strcat(data_section, "fmt_int:\n .ascii \"%d\\n\\0\"\n");
if (!source_code || !output_asm) {
printf("Error: Could not open source or output files!\n");
return 1;
}
// Write the assembly header
fprintf(output_asm, ASM_START);
char line[256];
while (fgets(line, sizeof(line), source_code) != NULL) {
line[strcspn(line, "\n")] = 0; // Remove new line character
// --- 1. INSTRUCTION: PRINT STRING (print "text") ---
if (strncmp(line, "print \"", 7) == 0) {
char *end_quote = strrchr(line, '"');
if (end_quote) {
*end_quote = '\0';
char *text = line + 7;
int length = strlen(text) + 1; // +1 for the \n character
// Add string to data section with a unique label (txt0, txt1, etc.)
char temp_buf[256];
sprintf(temp_buf, "txt%d:\n .ascii \"%s\\n\"\n", text_count, text);
strcat(data_section, temp_buf);
// Generate assembly for the write syscall
fprintf(output_asm, " # --- print \"%s\" ---\n", text);
fprintf(output_asm, " mov rax, 1\n"); // sys_write
fprintf(output_asm, " mov rdi, 1\n"); // stdout
fprintf(output_asm, " lea rsi, [txt%d]\n", text_count); // text address
fprintf(output_asm, " mov rdx, %d\n", length); // text length
fprintf(output_asm, " syscall\n");
fprintf(output_asm, " # --- Exit Program Gracefully ---\n");
fprintf(output_asm, " mov rax, 60\n");
fprintf(output_asm, " mov rdi, 0\n");
fprintf(output_asm, " syscall\n\n");
text_count++;
}
}
// --- 2. INSTRUCTION: SET VARIABLE (a = 5 or b = 5) ---
else if (strncmp(line, "a = ", 4) == 0) {
int value = atoi(line + 4);
fprintf(output_asm, " # --- variable a = %d ---\n", value);
fprintf(output_asm, " mov r8, %d\n", value); // variable 'a' lives in register R8
}
else if (strncmp(line, "b = ", 4) == 0) {
int value = atoi(line + 4);
fprintf(output_asm, " # --- variable b = %d ---\n", value);
fprintf(output_asm, " mov r9, %d\n", value); // variable 'b' lives in register R9
}
// --- 3. INSTRUCTION: ADD (a += b) ---
else if (strcmp(line, "a += b") == 0) {
fprintf(output_asm, " # --- a += b ---\n");
fprintf(output_asm, " add r8, r9\n"); // Add R9 into R8
}
// --- 4. INSTRUCTION: PRINT VARIABLE (print_var a) ---
// --- 4. INSTRUCTION: PRINT VARIABLE (print_var a) ---
else if (strcmp(line, "print_var a") == 0) {
fprintf(output_asm, " # --- print_var a ---\n");
fprintf(output_asm, " sub rsp, 8\n"); // Align stack to 16 bytes for C functions!
fprintf(output_asm, " lea rdi, [fmt_int]\n");
fprintf(output_asm, " mov rsi, r8\n");
fprintf(output_asm, " xor eax, eax\n");
fprintf(output_asm, " call printf\n");
fprintf(output_asm, " add rsp, 8\n"); // Restore stack pointer right after!
fprintf(output_asm, "\n # --- Exit Program Gracefully ---\n");
fprintf(output_asm, " xor eax, eax\n"); // Sets return status code to 0 (Success)
fprintf(output_asm, " ret\n\n"); // Return cleanly to the operating system!
}
}
// fprintf(output_asm, "\n # --- Exit Program Gracefully ---\n");
// fprintf(output_asm, " xor eax, eax\n"); // Sets return status code to 0 (Success)
// fprintf(output_asm, " ret\n\n"); // Return cleanly to the operating system!
// End of program and append the data section
fprintf(output_asm, ASM_EXIT);
fprintf(output_asm, "%s", data_section);
fclose(source_code);
fclose(output_asm);
system("gcc -no-pie -Wl,-z,noexecstack -Wl,--entry=main -o program.elf output.s");
printf("Assembled! Generated file: output.s\n");
printf("Compiled! Generated file: program.elf\n");
return 0;
}