带有 intel x86-32 位程序集的 gcc:访问 C 函数参数

sne*_*ehm 1 x86 assembly gcc inline-assembly osdev

我在做一个操作系统的实现工作。
首先是代码:

//generate software interrupt
void generate_interrupt(int n) {

    asm("mov al, byte ptr [n]");
    asm("mov byte ptr [genint+1], al");
    asm("jmp genint");
    asm("genint:");
    asm("int 0"); 
}
Run Code Online (Sandbox Code Playgroud)

我正在用-masm=intelgcc 中的选项编译上面的代码。此外,这不是生成软件中断的完整代码。

我的问题是我收到错误n undefined,我该如何解决,请帮忙?

它也在链接时而不是在编译时提示错误,下面是一个图像在此处输入图片说明

zwo*_*wol 5

当您使用 GCC 时,您必须使用GCC 样式扩展asm来访问在 C 中声明的变量,即使您使用的是 Intel 汇编语法。将 C 变量名直接写入程序集插入的能力是 MSVC 的一个特性,GCC 不会复制它。

对于这样的构造,使用单个装配插入物也很重要,而不是连续使用多个;GCC 可以并且将会相对于周围代码重新排列程序集插入,包括相对于其他程序集插入,除非您采取特定步骤来阻止它。

这个特殊的结构应该写成

void generate_interrupt(unsigned char n)
{
    asm ("mov byte ptr [1f+1], %0\n\t"
         "jmp 1f\n"
         "1:\n\t"
         "int 0"
         : /* no outputs */ : "r" (n));
}
Run Code Online (Sandbox Code Playgroud)

请注意,我已经删除了初始mov和任何涉及 A 寄存器的坚持,而是告诉 GCCn"r"输入约束加载到任何方便的寄存器中。最好在汇编插入中尽可能少做,并将寄存器的选择尽可能多地留给编译器。

我还更改了nto的类型unsigned char以匹配 INT 指令的实际要求,并且我正在使用1f 本地标签语法,以便generate_interrupt在制作内联函数时可以正常工作。

说了这么多,我恳请您为您的操作系统找到一种不涉及自修改代码的实现策略。好吧,除非您打算从自我修改中获得更多用途,否则。