在GCC内联汇编中,ljmp语法是什么?

4
我在考虑使用far jump来设置代码段(CS)寄存器。解释我为什么要这样做以及为什么我要处理分段需要花费一些时间,所以请耐心等待并将其视为学术练习。我似乎无法正确使用语法。
错误:'ljmp'的后缀或操作数无效
我知道将cs放入另一个寄存器中是愚蠢的,但我认为我应该尝试一下,因为使用%0不起作用(ax寄存器也不起作用)。
我正在查看一些编译良好的代码,这让我感到疯狂,因为我认为ljmp会是相同的:
__asm volatile ( "lcall $0x8, $far_call" );
当然,我也欢迎其他影响CS寄存器的hacky方法。
void set_cs(u16 cs) {
    __asm__ volatile (
        "mov %0, %%ax \n\t"
        "ljmp %%ax, $fake_label \n\t"
        "fake_label: \n\t"
        :
        : "r" (cs)
        : "ax"
    );
}

嵌入式汇编实在太麻烦了,为什么不直接在真正的汇编文件中编写真正的汇编例程呢? - Carl Norum
你确定通过阅读英特尔手册,可以用寄存器而不是即时数编码吗?我仍然无法解码那个东西 :-) - Ciro Santilli OurBigBook.com
1个回答

2
似乎ljmp需要常量才能工作,尽管这会生成更多代码并且显然不是特别安全的,但只要我输入一个不是当前cs值的值,应用程序就会崩溃。它使用了一个立即值:
#define set_cs( cs ) asm volatile ( "ljmp %0, $fake_label \n\t fake_label: \n\t" :: "i"(cs) )
这不像您想要的那样优雅,并且完全取决于您要做什么。如果您将其编译以在Linux / Windows下运行,则无法想象此方法是否有用或运行。

2
远跳转用于独立代码(例如操作系统代码)中,以指定代码段选择器(即使在x86_64中,它们也用于指定特权级别,即内核/用户空间)。我同意,在用户空间代码中这没有太多意义... - vyudh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接