【问题标题】:How do i use fs:bx in call instruction at Flat Assembler?如何在 Flat Assembler 的调用指令中使用 fs:bx?
【发布时间】:2016-08-13 01:37:41
【问题描述】:

我正在创建一个内核,我需要一些关于调用指令的帮助。我正在使用 Flat Assembler 构建内核。

call fs:bx

这可能吗?
因为平面汇编程序给了我一个“操作数大小无效”的错误。

我知道我能做到

call 1000h:0h

但这不是我想要的。有人知道这个问题的答案吗?

【问题讨论】:

    标签: assembly x86 kernel fasm


    【解决方案1】:

    我假设您希望 call fs:bxcs=fsip=bx 设置为远调用。

    间接远调用需要 seg:offset 在内存中,而不是在寄存器中。请参阅 the insn ref entry for call 以确认唯一可用的间接 far callcall m16:16 表单。

    所以在 16 位代码中,你可以

    push   fs
    push   bx
    ...    ;  push args
    far call   [bp-whatever]       ; assuming you know the difference between bp and sp at this point
    add    sp, 4 + arg_size     ; clean up args and the far-pointer
    

    或者提前在堆栈上预留空间,这样你就可以做类似的事情

    my_function:
        push       bp
        mov        bp, sp
        sub        sp, 16          ; or whatever size you need for locals.  16 and 8 are just for example.
    
        ...
    
        mov        [bp - 8], fs
        mov        [bp - 6], bx    ; separately store both parts of fs:bx into [bp-8]
        far call   [bp - 8]
    
        ...
        leave
        ret
    

    您不能mov cs, fs 或类似的东西(即使使用临时GP 寄存器)。更改 cs 将是一个跳跃,因此您必须将整个事情作为一个 far call 来完成。


    当然,你可能只把fs中的段值放在最前面来设置这条指令,所以一开始就不要这样做。

    【讨论】:

    • 我有一个问题:在你的例子中“随便”是什么意思?
    • @SeeSoftware:它是一个数值常量,取决于堆栈帧的大小(即推入 fs 和 bx 后 bp 和 sp 之间的差异。)等效地,您可以在函数的堆栈中保留一些空间提前这样你就可以mov [bp - 8], fs / mov [bp - 6], bx / ... / call [bp - 8]
    • 实际上你可以只使用 [sp] 而不是 [bp-whatever] 并且它对我来说很好,顺便说一句如何从中返回? “ret”或“retf”或其他东西编辑:你不能直接使用 sp 你必须把它放到另一个寄存器中
    • @SeeSoftware:是的,16 位代码对寻址模式有烦人的限制,请参阅the x86 tag wiki。是的,你需要做一个遥远的回报。我从来没有写过用远指针做任何事情的 16 位代码,但我认为远调用只是将 cs:ip 推送到 retf 可以弹出它的地方。 IDK 远返回的 FASM 语法是什么,但您可以使用反汇编程序检查以确保它生成了 0xCB opcode。我不喜欢 16 位代码,如果你还不了解 x86,我不推荐它作为学习 asm 的一种方式。
    • 调用后如何修复/清除堆栈?我不是堆栈方面的专家,但我认为你只需要增加堆栈指针?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多