我需要用MIPS汇编语言设置64位MMIO寄存器的第63位(MSB)。
目前我正在这样做
ldi $2,0x8000000000123456 #This is the address of the register which i want to set 63 rd bit
ld $3,0($2) # read current value from the register
dli $4,0x8000000000000000 # set 63rd bit as 1 and load in to register $4
dadd $4,$3,$4 # add mask value and current value to set 63rd bit
sd $4,0($2)
但这是非常冗长的代码。我想以最优化的方式做到这一点。还有其他办法吗?
答案 0 :(得分:2)
你的程序错了。从技术上讲,这是
uint64_t p = *((uint64_t*)0x8000000000123456ULL);
p += 0x8000000000000000ULL;
实际上切换顶部位,如果值设置了最高位,则不会给出正确的值。实际上,如果设置了最高位,它将陷入陷阱,因为它是dadd
而不是daddu
您应该详细了解bitwise operations:To clear a bit, use and
; use or
to set and xor
to toggle a bit
在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)