GNU C: базовый вызов asm-стека перед вызовом функции вызвал различное поведение в Mac и Linux - PullRequest
0 голосов
/ 27 марта 2019

Я пишу крошечный компилятор на платформе 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 что-то не так. Спасибо.

...