Я беру класс проектирования операционных систем, в котором нам дали микроядро, написанное на C, над которым мы строим. Ядро, похоже, было разработано с учетом 32-битных машин, и я использую снежного барса. Итак, друг в классе, и я пытался взломать его на 64-битную адресацию.
Самая большая проблема - одна строка кода, где встроенная сборка используется для копирования текущего указателя стека во временную переменную, используемую диспетчером:
#define SET_STACK(s) asm("movl temp,%esp");
Естественно, компилятор выдает мне ошибки, потому что %esp
- это 32-битный регистр.
/var/folders/0A/0AVWZC-5HhOg6twWZBlDgU+++TI/-Tmp-//cckS2oq7.s:523:32-bit absolute addressing is not supported for x86-64
/var/folders/0A/0AVWZC-5HhOg6twWZBlDgU+++TI/-Tmp-//cckS2oq7.s:523:cannot do signed 4 byte relocation
Поэтому я заменил его на %rsp
, потому что это 64-битный регистр указателя стека (и я думаю, что %sp
также работает, я где-то здесь читал, что GAS достаточно умен, чтобы поставить правильный префикс). После замены %esp
на %rsp
я получаю эту ошибку:
/var/folders/0A/0AVWZC-5HhOg6twWZBlDgU+++TI/-Tmp-//cc8TLdjH.s:523:Incorrect register `%sp' used with `l' suffix
Теперь я немного растерялся, потому что я не очень разбираюсь в ассемблере. Я пытался заменить movl
на mov
и movq
, но, похоже, ничего не работает. Что заставляет меня верить, что, возможно, temp
- это неправильный размер?
Temp - глобальная переменная, объявленная так:
void* temp; // temp pointer used in dispatcher
Я написал быструю программу для распечатки размеров разных типов данных, и кажется, что void * в x86-64 имеет размер 8 байт, который должен быть правильного размера, верно?
В любом случае, очевидно, я не ожидаю, что кто-нибудь решит эту проблему для меня, но любые советы, которые могут указать мне правильное направление, будут высоко оценены!