【发布时间】:2017-08-26 06:00:10
【问题描述】:
我在内存中有一个数组,其中包含描述汇编指令的某些十六进制值。例如:
708877665544332211 = jump 0x1122334455667788
70 表示汇编中的跳转,以下十六进制数字是我需要连接的。我已经试过了,
address |= memory[1];
address |= memory[2]<<8;
address |= memory[3]<<16;
address |= memory[4]<<24;
address |= memory[5]<<32;
address |= memory[6]<<40;
address |= memory[7]<<48;
address |= memory[8]<<56;
输出的字符串是:
0x100: 708877665544332211 |跳转1432778700
我在连接中哪里出错了?
编辑:按照本杰明的建议,我将其更改为:
使用打印语句printf("APPEND: %016llx", address)进行调试,我发现uint64_t被更改为:
APPEND: 0000000000002211
APPEND: 0000000000332211
APPEND: 0000000044332211
APPEND: 0000000044332255
APPEND: 0000000044336655
APPEND: 0000000044776655
如果地址是 64 位整数,为什么它看起来像 32 位整数?
【问题讨论】:
-
我想观察一下为什么您的代码在第一种情况下无法按预期工作:关于
address |= memory[5]<<32;、address |= memory[6]<<40;、address |= memory[7]<<48;和address |= memory[8]<<56;存在整数提升的问题。例如,address |= memory[5]<<32;会将 memory[5] 提升为 int(在您的平台上为 32 位值)。如果您尝试将超过 32 位类型宽度的 32 位左移。这将导致未定义的行为,这也是您在address中获得异常结果的原因 -
您可以使用
address |= ((unsigned long long)memory[5])<<32之类的内容进行投射。这会将 memory[5] 转换为 64 位类型,然后对其执行移位。假设您将address定义为unsigned long long -
我有点惊讶,尽管编译器不会在编译时警告你这个问题。
标签: c assembly hex concatenation