2

假设我有一个地址和一个偏移量,例如:

   char* base_addr = "\x00\x00\x00\xb7";
   char* addr_offset = (user input);

我想将 base_addr 和 addr_offset 一起添加。我是否必须编写自己的 strtol() 函数,该函数不会在 NUL 处终止,或者是否有另一种方法可以成功添加两个地址?

编辑:

忘了说这是Linux x86。

4

1 回答 1

1

base_addr实际上是一个 32 位整数值,恰好是使用字节常量硬编码的。您应该简单地将指针的类型转换为unsigned long,然后调用strtol()用户输入的字符串,并将两者相加。

以这种方式使用字符串对指针进行硬编码是很糟糕的。一方面,C 会在字符串的末尾添加一个 NUL 字节,所以现在您的 32 位值需要 5 个字节,并且添加了填充字节后,您最终可能会使用 8 个字节来存储您的指针,正好是需要的两倍. 最好这样做:

char base_addr[] = {'\x00', '\x00', '\x00', '\xb7'};

最好直接说出你的意思,只要编译器允许你进行类型转换:

unsigned char *base_addr = (unsigned char *)0xb7000000;

我刚刚检查过,GCC 允许您在没有错误或警告的情况下执行上述操作。

编辑:哦,好吧,真正的问题是如何访问整数值内的字节。

您应该能够通过弄乱指针来做到这一点:

unsigned long base_adr = 0xb700000000;
unsigned char *p = (unsigned char *)&base_adr;

上述技巧适用于整数类型。另一种方法是使用 C 联合:

typedef union
{
    char bytes[4];
    unsigned long n;
    unsigned char *ptr;
} ADR_WINDOW;

ADR_WINDOW x;

x.n = 0xb700000000;
assert(x.bytes[3] == 0xb7); // on a little-endian computer
assert(x.bytes[0] == 0xb7); // on a big-endian computer

union 技巧适用于任何类型,并且是唯一可移植的方法来执行低俗技巧,例如查看浮点值中的位。

于 2012-06-12T20:53:56.510 回答