【问题标题】:Given a memory address, how do I print the byte located at that address in C?给定一个内存地址,我如何在 C 中打印位于该地址的字节?
【发布时间】:2020-03-18 18:25:40
【问题描述】:

我还是 C 的新手,我在网上找到的关于如何完成的不同事情让我感到困惑。

为了验证 /proc/self/maps 中该地址是否存在某些内容,我将地址转换为无符号长整数值。

验证后,我想打印该地址的字节。

从我收集的信息来看,地址本身只是一个指向该字节的指针,因此我需要取消引用内存地址以获取该字节。

因此,如果我想将该字节打印为十六进制数字,则只需:

printf("%02x", *address)

任何意见将不胜感激。谢谢!

【问题讨论】:

    标签: c


    【解决方案1】:
    printf("%02x", (unsigned)*(unsigned char*)the_address_as_an_integer_or_pointer);
    

    说明:

    如果你想从一个地址中获取一个值,它需要一个指针类型。因此,您将其转换为指向char 的指针。 (严格的别名允许通过指向字符类型的指针获取任何值,其他指针类型受到更多限制)。转换为signed char * 会导致符号扩展(如果您想将值打印为unsigned,则不希望出现这种情况),因此您转换为*unsigned char。然后你取消引用 (*)。 这样的*(unsigned char*)address 具有unsigned char 类型,当通过printf... 时,它被提升为int。这通常适用于"%x",但要完全满足标准,"%x" 需要unsigned,因此最终转换为unsigned

    【讨论】:

    • 是否需要第二次演员表? (unsigned)
    • @FiddlingBits 学究式是(否则 UB),实际上不是。
    • @FiddlingBits 我相信printf 规则不幸需要精确的类型/说明符对应。 va_arg 规则更为宽松——只要值可以表示为 unsigned,您就可以将采用的 signed(与 va_arg)作为 unsigned 传递(我的相关问题:@987654321 @)。 (很迂腐地说,printf 不需要用va_arg 实现。)
    • volatile 也是需要的,尤其是如果您想多次阅读它\
    • @P__J__ 好吧,只有当内存有特殊硬件支持或者您正在使用信号处理程序时。然后,您也可能与另一个线程竞争,然后甚至 volatile 都不够。
    【解决方案2】:
    #define UCPTR(addr)   (volatile unsigned char*)(addr) 
    
    printf("0x%02hhx", *UCPTR(address));
    

    为了防止质疑为什么volatile

    #define UCPTR(addr)   (volatile unsigned char*)(addr) 
    #define NVUCPTR(addr)   (unsigned char*)(addr) 
    
    void foo()
    {
        while(*NVUCPTR(0x4564));
    }
    
    void bar()
    {
        while(*UCPTR(0x4564));
    }
    

    以及生成的代码:

    foo:
            cmp     BYTE PTR ds:17764, 0
            je      .L1
    .L3:
            jmp     .L3
    .L1:
            ret
    bar:
    .L6:
            movzx   eax, BYTE PTR ds:17764
            test    al, al
            jne     .L6
            ret
    

    我认为代码是不言自明的

    能否以其他方式存档? 可以,但不可移植,例如:

    void foo()
    {
        while(*NVUCPTR(0x4564)) asm("":::"memory");
    }
    

    https://godbolt.org/z/5Jkhp5

    【讨论】:

    • 第二部分是针对挑剔者的(例如“为什么volatile?”)。他们可以阅读汇编程序
    • "为什么volatile?" 并不是一个挑剔的人;这是一个很好的问题,即使是非专家也可能会问。程序集列表本身并不能真正回答问题。
    猜你喜欢
    • 2015-08-01
    • 2017-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    相关资源
    最近更新 更多