使用内联汇编

时间:2016-11-21 22:40:49

标签: c visual-c++ assembly x86 inline-assembly

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

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:

    }
}

将codify视为类型

的函数
unsigned char codify(unsigned char parameter) {
    unsigned char resp;

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

我已经测试过codify并且使用C代码返回我想要的值。问题是当我运行并调试内联汇编中的convertText代码时,我将其标记为&#34; - &gt;这里&#34;在eax中返回的值是3424242类型,而不是ascii表中的97或更高,这是我需要的。

如何获取char值?

2 个答案:

答案 0 :(得分:3)

Windows ABI显然不需要返回char的函数将值零或符号扩展为EAX,因此您需要假设AL上方的字节保持垃圾。 (这与the x86 and x86-64 System V ABI中的相同。另请参阅ABI /调用约定文档的标记wiki。

你不能假设在调用codify()之前将EAX归零就足够了。在使用AL中的char返回之前可以自由地使用所有EAX作为临时寄存器,但是垃圾进入EAX的其余部分。

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

答案 1 :(得分:1)

unsigned char只有1个字节,而eax是32位(4字节)寄存器。如果codify()仅返回1个字节,则返回值将存储在aleax的第一个字节)中,同时保留eax的其余部分(这将是导致垃圾)。在调用xor eax, eax之前,我建议codify(),以便在将返回值存储到寄存器之前知道寄存器是干净的。