【问题标题】:Inline assembly printf interpreting integers as an address内联汇编 printf 将整数解释为地址
【发布时间】:2020-06-06 22:32:32
【问题描述】:

我正在尝试通过内联程序集打印数组。 Printf 函数将堆栈上的值解释为它需要打印的地址并导致错误(屏幕截图:https://prnt.sc/r692d3)。如果我将地址传递给 printf,它会打印出像这样的垃圾值:(屏幕截图:https://prnt.sc/r691de)。 另外,如果有人知道 - 如何将 '\n' 放在带有内联 ASM 的字符串中?谢谢:)

int main()
{
    int mas[5] = { 1,2,3,4,5 };
    int32_t diff = sizeof(int);
    __asm
    {
        mov esi, 0x0

        lea ecx, [mas]
        mov eax, [ecx]
        push ecx
        call printf; Here it tries to read value '1' as an address
        pop eax

        loop_t:

        xor ebx, ebx; Clear the registers
        xor ecx, ecx;

            lea ecx, [mas]; ECX = &mas
            mov ebx, diff;
        add ebx, ecx; &mas + diff
        mov eax, [ebx]; Transfer the value
        push eax; Push it on stack
        call printf; Same thing here, interprets it as an address
            pop eax;
            add diff, 0x4;
            inc esi; Cleanup process and looping back on
            cmp esi, 0x5;
            jne loop_t;
    }
}

【问题讨论】:

    标签: c++ inline-assembly


    【解决方案1】:

    printf 函数的第一个参数是格式字符串,即指向以空字符结尾的字符数组的第一个字符的指针。因此,第一个参数将始终被视为地址。

    如果您将值 1 作为第一个参数传递给 printf(最后将其压入堆栈),那么它将尝试从地址 1 读取格式字符串(这将失败)。

    【讨论】:

    • 这很奇怪。因为在简单的情况下,例如将 const char 值推入堆栈,它会正确读取并打印它
    • @Raicha:通过“将 const char 值推入堆栈”,您的意思是您实际上是将单个 ASCII 代码 value 推入堆栈,而不是char?
    • Const char* 是地址
    • @Raicha:但是在您的第一条评论中,您写的是“const char value”,而不是“const char *”?是不是搞错了?
    • @Raicha:如果您将一个简单的字符串(空终止字符数组的第一个元素的地址)作为第一个参数传递给 printf,那么这可能会起作用,因为它被视为格式字符串。这就像写printf( "This is a string" ); 而不是printf( "%s", "This is a string" ); 如果字符串包含格式化字符,例如'%',这将不起作用。在这种情况下,您必须使用两个 '%' 转义这些格式字符。
    猜你喜欢
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-16
    • 1970-01-01
    相关资源
    最近更新 更多