1

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)

しかし、これは非常に長いコードです。私はそれを最も最適化された方法でやりたいと思っています。それを行う他の方法はありますか?

4

1 に答える 1

2

あなたのプログラムは間違っています。技術的にはこれを行っています

uint64_t p = *((uint64_t*)0x8000000000123456ULL);
p += 0x8000000000000000ULL;

これは実際に上位ビットを切り替え、値に上位ビットが設定されている場合は正しい値を提供しません。実際、最上位ビットが設定されている場合はトラップされますdadddaddu

ビット単位の操作について詳しく読む必要があります。ビットクリア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 デバイスにアクセスしている場合は、特定のバイト、ハーフワード、またはワードをロードして編集するだけで代替ソリューションが得られます。

# 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)
于 2014-06-15T04:13:37.697 に答える