これは宿題ですか?
ビットはビットです。ビット、バイト、ワード、ダブルワード、これらはハードウェア用語であり、命令セット/アセンブラが参照するものです。16進数、10進数、8進数、符号なし、符号付き、文字列、文字などは、プログラミング言語の表現です。同様に、.text、.bss、.dataなどもソフトウェアツールの表現であり、命令セットは1つのアドレスが.dataであり、もう1つが.textであることを気にせず、どちらの方法でも同じ命令です。これらのプログラミング言語がすべて存在する理由はいくつかありますが、非常に正当な理由がある場合もありますが、この問題を解決しようとするときに混乱しないでください。
ビットから人間が読める形式のASCIIに変換するには、最初にASCIIテーブル、ビット単位の演算子、または論理シフト、算術シフトなどを知る必要があります。さらに、ロードとストアなどが必要です。
レジスタ/メモリ内のある数値からASCII16進数に変換するために必要なことを数学的に考えてください。0b0001001000110100である0x1234と言います。人間がそれを読むためには、はい、より良い用語がないために文字列に入れる必要がありますが、何かをするために隣接するメモリ位置に4文字とnullを格納する必要はありません。出力関数によって異なります。通常、文字ベースの出力エンティティは、何度も呼び出されるある種の単一のoutput_char()に要約されます。
文字列に変換することもできますが、それはより手間がかかります。計算するASCII文字ごとに、ある種の単一文字ベースの出力関数をすぐに呼び出します。putchar()は、バイト出力文字タイプ関数の例です。
したがって、バイナリの場合、一度に1ビットを調べて、0x30または0x31を作成する必要があります。8進数の場合、一度に3ビットで、0x30から0x37を作成します。16進数は、一度に4ビットに基づいています。
16進数には、使用する16文字がASCIIテーブルで互いに隣接して見つからないという問題があります。したがって、0〜9の場合は0x30〜0x39を使用しますが、好みや要件に応じて、A〜Fの場合は0x41〜0x46または0x61〜0x66を使用します。したがって、各ニブルについて、0xFとANDで比較し、9と比較して0x30または0x37を追加します(10 + 0x37 = 0x41、11 + 0x37 = 0x42など)。
レジスタ内のビットからバイナリのASCII表現への変換。メモリ内のビットが1である場合、ビットの1(0x31 ascii)は0であり、0(asciiでは0x30)を示します。
void showbin(unsigned char x)
{{
unsigned char ra;
for(ra = 0x80; ra; ra >> = 1)
{{
if(ra&x)output_char(0x31); else output_char(0x30);
}
}
上記のunsignedcharを使用するのは理にかなっているように思われるかもしれませんが、unsigned intは、ターゲットプロセッサによっては、はるかに優れた(よりクリーンで高速な)コードを生成できます。しかし、それは別のトピックです
上記は、アセンブラでは次のようになります(意図的にx86を使用していません)
..。
mov r4、r0
mov r5、#0x80
上:
tst r4、r5
moveq r0、#0x30
movne r0、#0x31
bl output_char
mov r5、r5、lsr#1
cmp r5、#0
bneトップ
..。
展開すると書き込みが簡単になり、少し速くなります。トレードオフは、より多くのメモリを使用することです。
..。
tst r4、#0x80
moveq r0、#0x30
movne r0、#0x31
bl output_char
tst r4、#0x40
moveq r0、#0x30
movne r0、#0x31
bl output_char
tst r4、#0x20
moveq r0、#0x30
movne r0、#0x31
bl output_char
..。
9ビットの数値があり、8進数に変換したいとします。一度に3ビットを取り(人間は左から右に読むので、上のビットから始めます)、0x30を追加して0x30から0x37を取得します。
..。
mov r4、r0
mov r0、r4、lsr#6
およびr0、r0、#0x7
r0、r0、#0x30を追加します
bl output_char
mov r0、r4、lsr#3
およびr0、r0、#0x7
r0、r0、#0x30を追加します
bl output_char
およびr0、r4、#0x7
r0、r0、#0x30を追加します
bl output_char
..。
16進数の1バイト(8ビット)は次のようになります。
..。
mov r4、r0
mov r0、r4、lsr#4
およびr0、r0、#0xF
cmp r0、#9
addhi r0、r0、#0x37
addls r0、r0、#0x30
bl output_character
およびr0、r4、#0xF
cmp r0、#9
addhi r0、r0、#0x37
addls r0、r0、#0x30
bl output_character
..。
1からNまでのループを作成し、その値をメモリに格納してメモリ(.data)から読み取り、16進数で出力します。
..。
mov r4、#1
str r4、my_variable
..。
上:
ldr r4、my_variable
mov r0、r4、lsr#4
およびr0、r0、#0xF
cmp r0、#9
addhi r0、r0、#0x37
addls r0、r0、#0x30
bl output_character
およびr0、r4、#0xF
cmp r0、#9
addhi r0、r0、#0x37
addls r0、r0、#0x30
bl output_character
..。
ldr r4、my_variable
r4、r4、#1を追加します
str r4、my_variable
cmp r4、#7;たとえばNは7です
bneトップ
..。
my_variable .word 0
十分なレジスタがある場合、RAMに保存するのは少し無駄です。x86を使用すると、メモリを直接操作でき、レジスタを経由する必要はありません。
x86は、上記の(ARM)アセンブラーと同じではないため、同等の機能を理解するための演習として残されています。重要なのは、それはシフトとアンディングであり、その問題を追加して、それを基本的なステップに分解し、そこから指示が自然に落ちるということです。