Я пишу базовый компилятор, и сгенерированный код не работает должным образом.
Я использую наивный алгоритм раскраски графиков для распределения переменных в регистрах на основе их жизнеспособности.
Проблема в том, что сгенерированный ассемблерный код выглядит совершенно нормально, но в какой-то момент он вызывает неопределенное поведение.
Если вместо использования регистров для хранения переменных я просто использую стек, все работает нормально.
Я также обнаружил, что не могу использовать регистр %edx
вокруг инструкции imull
, и мне стало интересно, происходит ли что-то подобное прямо сейчас с %ebx
и %ecx
.
Я компилирую код, используя gcc -m32 "test.s" runtime.c -o test
, где runtime.c
- вспомогательный файл C, содержащий функции печати и ввода.
Я также пытался удалить части программы (каждый отпечаток, кроме последнего), а затем будет работать последний отпечаток.
Если я вызову одну функцию печати до последнего вызова, она не будет работать.
Файл runtime.c
:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
int input() {
int num;
char term;
scanf("%d%c", &num, &term);
return num;
}
void print_int_nl(int i) {
printf("%d\n", i);
}
Исходный файл:
a = 10
b = input()
c = - 10
d = -input()
print a
print b
print c
print d
Сгенерированный код сборки:
https://pastebin.com/ChSRbWgt
После компиляции файла .s и запуска его с помощью консоли (./test
) он запрашивает 2 ввода (как и предполагалось).
Я даю это 1 и 2.
Тогда вывод:
10
1
-10
1415880
вместо
10
1
-10
-2