所以我正在写一个非常小而简单的程序,它以数字为输入,将其转换为十六进制,并一次打印出两个字符。
对于某些数字,它会在输出前打印出ffffff。
这是我的代码:
//Convert the input to an unsigned int
unsigned int a = strtoul (argv[1], NULL, 0);
//Convert the unsigned int to a char pointer
char* c = (char*) &a;
//Print out the char two at a time
for(int i = 0; i < 4; i++){
printf("%02x ", c[i]);
}
大部分输出都很好,看起来像这样:
./hex_int 1
01 00 00 00
但对于一些数字,输出看起来是这样的:
./hex_int 100000
ffffffa0 ffffff86 01 00
如果你去掉所有的f,转换是正确的,但我不明白为什么它只在一些输入上这样做。
有人有什么想法吗?
您的参数和打印格式不匹配。默认参数promotions会将char
参数(c[i]
)提升为int
,该符号扩展(显然char
是一个签名类型)。然后,您告诉printf
使用%x
格式将该参数解释为unsigned int
。动臂-未定义的行为。
用途:
printf("%02x ", (unsigned int)(unsigned char)c[i]);
相反。
char
在您的系统上签名。将int移到其中会使编译器认为您希望在需要转换为int的操作中使用最高位作为符号位。将其打印为十六进制数就是一。
将字符指针c
设置为unsigned char *
,问题就会消失。
如果Carl的评论是正确的(我要检查一下),请使用这种故障保护方法:
printf("%02x ", c[i] & 0xff);
我在那里做了一段时间,我意识到,你可以在一个进程中看到exe映像,使用调试器,代码是可以的,但我暂时不能将这段机器代码传递给汇编程序,但好吧,有了指针,就一切皆有可能
include stdio.h
include windows.h
int main ()
{
int i=0;
char * p = (char *)0x400000;
for(int i = 0; i < 20; i++)
{
printf("%p %02x n",p+i, (unsigned int)(unsigned char)*(p+i));
}
}
好吧,添加windows.h是为了使用一些系统调用,我在示例中省略了这些,因为没有必要使用下面代码中的那些,关于unsigned,是的,它可以被提交,因为char总是>0,关于地址,如前所述,0400000是exe的头,在这种情况下是"mz"头,但进程的dll代码可能是7c911000,和dll的头另一个地址,等等。。,这个信息在exe文件中,必须读取才能知道加载的图像在主内存中的加载位置,但当你只有一个进程时,如果你有更多的进程,你必须使用系统调用来知道第二个进程在哪里,如果一个地址不可读,只需在记事本中读取de.exe,该地址只是的一个示例