ええと、それを書く必要があります... または誰かがすでに書いたものを借ります。後者の方が簡単ですが (C ライブラリにはこのような関数があり、asm から簡単に呼び出すことができます)、前者の方が「楽しい」です。(そういうのが好きなら、クロスワードパズルをする人もいます)
指導はdiv
とても遅いです。逆数と「逆乗算」を掛けることに基づいて、それを行うより良い方法があります。かなり複雑です。お待ちしておりdiv
ます。:)
div ebx
番号、たとえば 1234 を に配置しeax
、10 を配置した場合ebx
、123 にeax
4が配置されますedx
(ebx
は変更されません)。実際には、 ...edx
の前に0 を入れたいと思います。div
xor edx, edx
div ebx
ご存じのように、文字「0」(または 10 進数の 48 または 30h) を追加することで、数値 4 を文字「4」に変換できます。これで、印刷できるものができました!しかし、まだ印刷する準備ができていません。桁を逆に取得しています。これに対処するにはいくつかの方法があります。push
最も簡単なのは、スタック上に置くことだと思います。pop
正しい順序でそれらをオフにします。もう 1 つの方法は、先に進んでバッファーに逆方向に配置し、最後に「文字列の反転」を行うことです。もう 1 つの方法は、バッファーの「最後」から始めて、先頭に向かって作業することです (インデックスをインクリメントするのではなく、各文字の後にバッファーにデクリメントします)。これは、桁がなくなったときにバッファの先頭に達していないことを意味する場合があります。これを有利に利用できます。列に印刷する場合は、右揃えの数値が見栄えがします。見栄えが良いと思われる場合は、先行ゼロ (数字の 0 ではなく文字「0」) で埋めることもできます (私はしません)。
いずれにせよ、「4」は安全に保管されています。何度もループしますdiv
(edx
最初にゼロにします!)。これで 12 インチeax
と 3インチになりましたedx
。3で何かをして、div
もう一度戻ってください。1インチeax
と2インチedx
。繰り返しますが、 andeax
は 0 (edx
は 1) です - その時点で完了です! div
9と比較すると、最後の桁をスキップできます。9 より小さい場合は、代わりにeax
から最後の (最初に出力される) 桁を取得できます。毎回同じ方法で行う方が簡単です...
al
dl
; mov eax, the number
; mov edi, the buffer (at least resb 10, please)
; call dwtoa
; mov edx, eax ; count
; mov ecx, buffer
; print it
dwtoa:
xor ecx, ecx ; for a counter
mov ebx, 10
pushloop:
xor edx, edx ; or mov edx, 0
div ebx
add edx, '0'
push edx
inc ecx ; count it
test eax, eax ; or cmp eax, 0
jnz pushloop
mov eax, ecx ; we'll return the count in eax
poploop:
pop edx
mov [edi], dl
inc edi
loop poploop
ret
それは私の頭のてっぺんから外れており(カットアンドペーストではありません)、エラーがある可能性があります。それはかなりずさんです-Cが保存したいレジスタを破棄します-Cが望むようにゼロで終わる文字列を返しません...しかし、私たちはCを使用していないので気にしません! :)
好みに合わせて改良するか、別の方法を試してみてください。
ユーザーが入力したテキストを数値に変換するには、"atoi" (または同じ命名規則を使用する "atodw") を使用する必要があります。同じ考えですが、文字から「0」を引き、「これまでの結果」に 10 を掛け、新しい数字を足します... 完了するまで。
;-------------------
; atoi - converts string to (unsigned!) integer
; expects: buffer in edx
; returns: number in eax
atoi:
xor eax, eax ; clear "result"
.top:
movzx ecx, byte [edx]
inc edx
cmp ecx, byte 0
jz .done
cmp ecx, byte 10
jz .done
cmp ecx, byte '0'
jb .invalid
cmp ecx, byte '9'
ja .invalid
; we have a valid character - multiply
; result-so-far by 10, subtract '0'
; from the character to convert it to
; a number, and add it to result.
lea eax, [eax + eax * 4]
lea eax, [eax * 2 + ecx - '0']
jmp short .top
.invalid:
stc
.done:
ret
;--------------
それはカットアンドペーストなので、「うまくいく」はずです。それもまた、改善される可能性があります。「興味深い」方法を使用して、10 を掛け、数値に変換された新しい文字を追加します。この時点で、プログラムの「作業」は
次のadd eax, 1
ようになります。楽しむ!:)