Я пишу крошечный компилятор на платформе x86. Когда я тестировал встроенный код ассемблера в Linux и Mac OS, я обнаружил, что этот фрагмент кода имеет разное поведение на этих двух платформах.
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
void ret() {
std::cout << "haha" << std::endl;
}
int main(int argc, char *argv[])
{
asm volatile ("sub $0x08, %rsp"); // on linux okay, but on macOS will SIGSEGV. After changing it to `asm volatile ("sub $0x10, %rsp");`, macOS platform behaves well.
asm volatile ("mov %r15, 0x0(%rsp)");
asm volatile ("mov %0, %%r10"::"r"((void*)ret));
asm volatile ("call *%r10");
asm volatile ("int $0x03");
}
Ошибка до достижения программной точки останова int3
.
Я хочу сохранить (нажать) регистр r15, чтобы сохранить его (хотя я знаю, что это регистр, сохраненный вызываемым абонентом), и я не думал, что в sub $0x08, %rsp
что-то не так.
Спасибо.