Я посещаю занятия по проектированию операционных систем, на которых нам дали микроядро, написанное на языке C, на основе которого мы строим. Ядро, кажется, было разработано с учетом 32-битных машин, и я использую Snow Leopard. Итак, мы с другом в классе пытались взломать его до 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 байтов, что должно быть правильным размером, верно?
В любом случае, очевидно, я не ожидаю, что кто-то решит эту проблему за меня, но любые советы, которые могут указать мне правильное направление, будут высоко оценены!