【发布时间】:2016-08-13 01:37:41
【问题描述】:
我正在创建一个内核,我需要一些关于调用指令的帮助。我正在使用 Flat Assembler 构建内核。
call fs:bx
这可能吗?
因为平面汇编程序给了我一个“操作数大小无效”的错误。
我知道我能做到
call 1000h:0h
但这不是我想要的。有人知道这个问题的答案吗?
【问题讨论】:
我正在创建一个内核,我需要一些关于调用指令的帮助。我正在使用 Flat Assembler 构建内核。
call fs:bx
这可能吗?
因为平面汇编程序给了我一个“操作数大小无效”的错误。
我知道我能做到
call 1000h:0h
但这不是我想要的。有人知道这个问题的答案吗?
【问题讨论】:
我假设您希望 call fs:bx 将 cs=fs 和 ip=bx 设置为远调用。
间接远调用需要 seg:offset 在内存中,而不是在寄存器中。请参阅 the insn ref entry for call 以确认唯一可用的间接 far call 是 call 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中的段值放在最前面来设置这条指令,所以一开始就不要这样做。
【讨论】:
mov [bp - 8], fs / mov [bp - 6], bx / ... / call [bp - 8]
retf 可以弹出它的地方。 IDK 远返回的 FASM 语法是什么,但您可以使用反汇编程序检查以确保它生成了 0xCB opcode。我不喜欢 16 位代码,如果你还不了解 x86,我不推荐它作为学习 asm 的一种方式。