[解決済み] ビットシフト演算子を使って10進数を2進数で表示するMIPS
質問事項
このトピックに関するスレッドをここやネット上の他の場所で数多く読みました。 ビットシフトに関する素晴らしいトピック(必ずしもAssemblyに関連するものではありませんが、一般的なトピックは以下の通りです。 ビットシフト(bit-shift)演算子とは何ですか、またその仕組みは? OPのコードをここにコピー&ペーストするところまでやってみました。 入力された整数を2進数で表示するには? また、返信者が提案した変更を加えても、何をやってもゼロの文字列が生成されます。
ビットシフトとは何か、その仕組みは理解しています。 右に'n'シフトすると2^nで割り、左にシフトすると2^nで乗算します。
私は先週締め切られたラボを持っていて、その3番目の部分は、ユーザーの入力を受けて、その2進バージョン、そして16進バージョンをプリントアウトするプログラムを提供するというものでした。 それが終わると、プログラムは文字列の中心にある特定のビットをプリントアウトし、その2進数と16進数のバージョンも生成することになっていました。
私が最初に考えたのは、文字列を受け取って、0x01とANDして、その結果の「1」または「0」をプリントし、それを「1」だけ右にビットシフトすることでした。 これはループに含まれていて、カウンタが'32'の要件を満たすまで続けられ、それで終了します。 しかし、なぜすべて'0'をプリントしてしまうのか、非常に困っています。 他のバージョンも試してみたのですが、以下のような感じです。
-
ユーザー入力を31だけ左にシフトし、各ビットに対してループを実行するが、ループ内では(ビットの逆順にするために)右にシフトしていた - 失敗 - 再びすべて0になる
-
上記と逆の操作を行う - 再び失敗、すべてゼロになる
頭では分かっているのですが、このようなことをしたいのです。
(NOT CODE OBVIOUSLY)
User input is: 25 <-- store at $t0
Binary rep is: 0000 0000 0000 0000 0000 0000 0001 1001 # 25 in $t0
LOOP:
AND with 0x01: 0000 0000 0000 0000 0000 0000 0000 0001 #saved to $t1
Produces: 0000 0000 0000 0000 0000 0000 0000 0001 #saved to $t2
Print to Console: 1 #send contents of $t2 to syscall
Shift $t0 Right 1: 0000 0000 0000 0000 0000 0000 0000 1100 #
j LOOP (until the beq branch was met and I left the loop)
と思っていたのですが、これならうまくいきそうです。 たとえ結果が逆向きになったとしても、生成された文字列の中に'1'が含まれていたはずで、それに気づいて適切に対処できたと思います(数字全体を左にシフトして
$t0
を'31'差引いた後、上記の指示を実行しました。 まだ全部'0'です・・・。
これが私のコードです。 今また、私の数々の試行錯誤と変更により、破損してしまいました。 上記の私のアプローチが完全に的外れなのか、またこれを修正するために以下のサンプルコードに何ができるのか、理解するための手助けをお願いしたいのです。
この課題は提出済みで、私が混乱していたために完了しなかったことを理解してください。 私はこれをさらに理解したいと思っています。 この部分でつまずいたので、コード全体を完成させませんでした。 だから、この課題の最初の部分だけお願いします。
#Read integer A from user and store it into a register
#Display the integer in binary
#Display the integer in Hex
#set Register $a0 to contain only bits 12,13,14,15 of $a0
#Display the integer in binary contained in $a0
#Display the integer in hex contained in $a0
.data
userInput: .asciiz "Please enter your integer:\n"
binaryInput: .asciiz "Here is the input in binary: "
nl: .asciiz "\n\n"
hexInput: .asciiz "Here is the input in hexidecmal: "
binaryOutput: .asciiz "Here is the output in binary: "
hexOutput: .asciiz "Here is the output in hexidecimal: "
.text
main:
#ask end-user to submit an integer value
li $v0, 4
la $a0, userInput
syscall
#read user-input
li $v0, 5
syscall
#enter user input into $t0
move $t0, $v0
add $t1, $zero, $zero #counter
addi $t2, $zero, 32 #target
sll $s1, $t0, 31 #shift left number 31 bits to s1
li $v0, 4
la $a0, binaryInput #print out string to user
syscall
loop:
andi $s2, $s1, 1 #and 0x01 with s1 to s2
srl $s1, $s1, 1 #shift right s1 by 1 bit
li $v0, 1
la $a0, ($s2) #print digit held in s2 to screen
syscall
add $t1, $t1, 1 #add 1 to counter
bne $t1, $t2, loop #check if counter is equal to target, if not continue loop
#exit the program
li $v0, 10
syscall
解決方法は?
ここで、あなたの基本的なアプローチとは少し異なる方法を紹介します。バイナリ出力と16進出力を共通の出力関数に対するパラメータとして扱います。ビットマスク/ビットシフトは似ていますが、マスクとビット幅は可変です。
# Read integer A from user and store it into a register
# Display the integer in binary
# Display the integer in Hex
# set Register $a0 to contain only bits 12,13,14,15 of $a0
# Display the integer in binary contained in $a0
# Display the integer in hex contained in $a0
.data
userInput: .asciiz "Please enter your integer: "
binaryInput: .asciiz "Here is the input in binary: "
nl: .asciiz "\n"
hexInput: .asciiz "Here is the input in hexadecimal: "
binaryOutput: .asciiz "Here is the output in binary: "
hexOutput: .asciiz "Here is the output in hexadecimal: "
hexDigit: .asciiz "0123456789ABCDEF"
obuf: .space 100
obufe:
.text
.globl main
main:
# ask end-user to submit an integer value
li $v0,4
la $a0,userInput
syscall
# read user-input
li $v0,5
syscall
move $s0,$v0
# output original in binary
la $a0,binaryInput
li $a1,32
jal prtbin
# output original in hex
la $a0,hexInput
li $a1,32
jal prthex
# isolate bits 12,13,14,15
srl $s0,$s0,12
andi $s0,$s0,0x0F
# output isolated in binary
la $a0,binaryOutput
li $a1,4
jal prtbin
# output isolated in hex
la $a0,hexOutput
li $a1,4
jal prthex
# exit the program
li $v0,10
syscall
# prtbin -- print in binary
#
# arguments:
# a0 -- output string
# a1 -- number of bits to output
prtbin:
li $a2,1 # bit width of number base digit
j prtany
# prthex -- print in hex
#
# arguments:
# a0 -- output string
# a1 -- number of bits to output
prthex:
li $a2,4 # bit width of number base digit
j prtany
# prtany -- print in given number base
#
# arguments:
# a0 -- output string
# a1 -- number of bits to output
# a2 -- bit width of number base digit
# s0 -- number to print
#
# registers:
# t0 -- current digit value
# t5 -- current remaining number value
# t6 -- output pointer
# t7 -- mask for digit
prtany:
li $t7,1
sllv $t7,$t7,$a2 # get mask + 1
subu $t7,$t7,1 # get mask for digit
la $t6,obufe # point one past end of buffer
subu $t6,$t6,1 # point to last char in buffer
sb $zero,0($t6) # store string EOS
move $t5,$s0 # get number
prtany_loop:
and $t0,$t5,$t7 # isolate digit
lb $t0,hexDigit($t0) # get ascii digit
subu $t6,$t6,1 # move output pointer one left
sb $t0,0($t6) # store into output buffer
srlv $t5,$t5,$a2 # slide next number digit into lower bits
sub $a1,$a1,$a2 # bump down remaining bit count
bgtz $a1,prtany_loop # more to do? if yes, loop
# output string
li $v0,4
syscall
# output the number
move $a0,$t6 # point to ascii digit string start
syscall
# output newline
la $a0,nl
syscall
jr $ra # return
関連
-
[解決済み】JNZとCMPのアセンブリ命令
-
[解決済み】MIPSで整数の絶対値?
-
[解決済み] MIPSプログラムの中で`lw`と`sw`が実際にどのように機能するかを理解する
-
[解決済み] BL命令ARM - その仕組み
-
[解決済み] アセンブリMIPS .ALIGNとメモリアドレスの理解
-
[解決済み] アセンブリ言語 - sarqはコードの中で何をするのですか?
-
[解決済み] objdumpの出力にあるdata16とはどういう意味ですか?
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
-
[解決済み】ビットシフト(bit-shift)演算子とは、どのようなもので、どのように機能するのですか?
-
[解決済み] Python 3.x の整数に対して、ビットシフトより速い Times-two?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] MIPSの大、小、大
-
[解決済み] アセンブリ - CMP後のJG/JNLE/JL/JNGE
-
[解決済み] MIPSプログラムの中で`lw`と`sw`が実際にどのように機能するかを理解する
-
[解決済み] Binary Bomb Phase_6 Node Order?
-
[解決済み] .quadディレクティブはアセンブリでどのように機能するのですか?
-
[解決済み] 8086アセンブリ言語での2つのレジスタのスワッピング(16ビット)
-
[解決済み] アセンブリのNEG
-
[解決済み] アセンブリで文字列の長さを表示する方法
-
[解決済み] アセンブリMIPS .ALIGNとメモリアドレスの理解
-
[解決済み】ビットシフト(bit-shift)演算子とは、どのようなもので、どのように機能するのですか?