使用内联汇编从 C 函数获取返回的字符

Get returned char from a C function using inline assembly

我有一个使用内联汇编的函数,它基本上调用 C 函数,获取返回值,并将该值作为参数传递给另一个 returns 字符的函数。

void convertText(FILE *arch, FILE *result)
{
    int i = 0;
    int n = arch->size;

    _asm {
    mov esi, 0
whileS:
    cmp esi, n
    jge end

    mov ebx, result
    mov ebx, [ebx]result.information ; Pointer to an array of characters

    push esi ; Push parameters to get5bitsFunc
    push arch ; Push parameters to get5bitsFunc

    call get5bitsFunc
    pop arch ; Restore values
    pop esi ; Restore values

    push eax ; push get5bitsFunc returned value to codify as parameter
    call codify
   mov edi, eax ;  <- HERE move returned value from codify to edi register
    pop eax ; restore eax

    inc esi
    jmp whileS
end:

    }
}

将编码视为类型的函数

unsigned char codify(unsigned char parameter) {
    unsigned char resp;

    // Do something to the parameter
    resp = 'b'; // asign value to resp
    return resp;
}

我已经测试过 codify 并且工作正常,可以使用 C 代码返回我想要的值。问题是,当我 运行 并在我标记为“-> Here”的行中调试内联汇编中的 convertText 代码时,eax 中返回的值是 3424242 类型,而不是 ascii 中的 97 或更高类型table 这就是我需要的。

如何获取字符值?

unsigned char 只有 1 个字节,而 eax 是一个 32 位(4 字节)寄存器。如果 codify() 只是 return 1 个字节,那么 return 值将存储在 aleax 的第一个字节),而剩下的eax 未动过(这会导致垃圾)。我建议在调用 codify() 之前使用 xor eax, eax,这样您就可以知道寄存器在存储 return 值之前是干净的。

Windows ABI 显然不需要返回 char 的函数将值零扩展或符号扩展到 EAX,因此您需要假设 AL 上方的字节包含垃圾。 (这与 ABI/calling 公约文档的 . See also the 标签维基相同)。

您不能假设在调用 codify() 之前将 EAX 置零就足够了。 在返回 char 之前可以免费使用所有 EAX 作为临时寄存器AL,但 EAX 的其余部分是垃圾。

您实际上需要 movzx esi, al、(或 MOVSX)或 mov [mem], al 或您想要执行的任何其他操作来忽略高字节中的垃圾。