你的程序是错误的。它在技术上这样做
uint64_t p = *((uint64_t*)0x8000000000123456ULL);
p += 0x8000000000000000ULL;
它实际上会切换最高位,如果该值设置了最高位,则不会为您提供正确的值。事实上,如果设置了最高位,它会陷入困境,因为这是dadd
而不是daddu
您应该阅读有关按位运算的更多信息:要清除一点,请使用and
; 用于设置和切换位or
_ _xor
在 MIPS 中你可以这样做
ldi $2, 0x8000000000123456
ld $3, 0($2)
lui $4, 0x8000 # $4 = 0x80000000
dsll $4, $4, 32 # $4 = 0x8000000000000000
or $4, $3, $4
sd $3, 0($2)
lui/dsll 对用于加载立即数。它可以替换为任何等效序列,将 2 的幂加载到低半部分,然后将其移到高部分
请注意,除非您使用 MMIO,否则没有所谓的“寄存器地址”。它是包含内存位置地址的寄存器。如果您正在访问实际内存或允许部分寄存器访问的 MMIO 设备,那么您有一个替代解决方案,只需加载特定字节、半字或字并对其进行编辑,这样可以节省几条指令来加载 64 位立即数
# byte
ldi $2, 0x8000000000123456 # assume big endian
lbu $3, 0($2)
ori $3, 0x80
sb $3, 0($2)
# halfword
ldi $2, 0x8000000000123456
lhu $3, 0($2)
ori $3, 0x8000
sh $3, 0($2)
# word
ldi $2, 0x8000000000123456
lbu $3, 0($2)
lui $4, 0x8000
or $3, $4, $3
sd $3, 0($2)