【问题标题】:Assembly equivalent of array of function pointers?函数指针数组的程序集等效?
【发布时间】:2015-09-03 22:09:59
【问题描述】:

在 C 语言中,如果我想根据键盘输入调用函数,我会写如下内容:

#include <stdio.h>

char A(void) {
        return 'a';
}

char B(void) {
        return 'b';
}

char C(void) {
        return 'c';
}

char (*CHARS[])(void) = {A, B, C};
int main(void) {
        char calls[] = {'a', 'b', 'c'};
        char c = CHARS[getc(stdin) - 'a']();
        printf("%c\n", c);
        return 0;
}

我可以在汇编中进行一系列调用吗?如果事实相关,我正在使用nasm 编译内核。

编辑 刚才又玩了一些,我想出了:

        jmp main
f0:
f1:
f2:
        mov     ax, 0
main:
        mov     bx, fns
        add     bx, ax
        cmp     bx, 0
        je      end
        call    [bx]
        inc     ax
        jmp     main
        fns     dw f0, f1, f2, 0
end:
        hlt

上面说的是否正确(我真的是两天后才开始组装)?

【问题讨论】:

  • 您更新的代码有正确的想法。但是:(1)您假设所有内容都是 16 位地址。那是你要的吗? (2)你可以摆脱ax的使用。假设是 16 位寻址模式,您希望每次通过 main 循环将 2 添加到 bx,(3)您要检查 [bx] 是否为 0,而不是 bx 是否为 0。bx不会为 0,因为它是指向地址表的指针。
  • @lurker 是的,它是 16 位模式。谢谢。

标签: c assembly kernel nasm bios


【解决方案1】:

您可以创建一个跳转表,并修改PC(程序计数器)以跳转到表中的正确索引。例如

    ADD PC, $c      # Add index entered by the user to the PC
    BRA function_a
    BRA function_b
    BRA function_c
end_jump_table:
    # ...

还有其他地方:

function_a:
    # do your thing
    BRA end_jump_table
function_b:
    # do your thing
    BRA end_jump_table
function_c:
    # do your thing
    BRA end_jump_table

不是用任何特定的汇编语言,但你明白了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-13
    • 1970-01-01
    • 2021-03-17
    相关资源
    最近更新 更多