我被困在一個實踐問題,我需要一個整數讀,把它加1,並打印出結果。關於這個問題:linux nasm assembly print all numbers from zero to 100,槍手用戶提到dwtoa。我假設這是一個可調用函數。那麼這個dwtoa函數是什麼?如果它實際上是一個可調用的函數,我可以在哪裏獲得它(通過獲取我的意思是如何在我的代碼中實現它?)?Linux的NASM彙編dwtoa
在此先感謝。
我被困在一個實踐問題,我需要一個整數讀,把它加1,並打印出結果。關於這個問題:linux nasm assembly print all numbers from zero to 100,槍手用戶提到dwtoa。我假設這是一個可調用函數。那麼這個dwtoa函數是什麼?如果它實際上是一個可調用的函數,我可以在哪裏獲得它(通過獲取我的意思是如何在我的代碼中實現它?)?Linux的NASM彙編dwtoa
在此先感謝。
嗯,啊,你必須把它寫...或借用一個有人在已經寫好。後者更容易(C庫具有這樣的功能,並且很容易從asm調用),但前者更「有趣」。 (如果你喜歡那種事 - 哎,有些人做填字遊戲)
的div
指令是很慢的。有一個更好的方法來實現它的基礎上乘以互惠和「後乘」。這很複雜。我們將等待div
。 :)
div ebx
如果我們安排了我們的號碼,說1234,在ebx
eax
和10,我們現在有eax
123和4 edx
(ebx
保持不變)。其實,我們會想在div
前edx
有0 ...
xor edx, edx
div ebx
如你所知,我們可以在4號轉換爲字符「4」通過增加字符'0'(或48小數或30h)。現在我們有一些我們可以打印的東西了!但我們還沒有準備好打印它 - 我們正在倒數字。有幾種方法可以解決這個問題。我認爲最簡單的方法是在正確的順序上將push
'堆棧和pop
'關閉。另一種方法是繼續前進,並將em放在緩衝區中,最後做一個「字符串反轉」。另一種方法是從緩衝區的「結尾」開始,向前移動(在每個字符之後將索引遞減到緩衝區,而不是遞增)。這可能意味着當數字用完時,您不在緩衝區的開頭。我們可以利用這個優勢 - 如果您打算在列中打印他們,則右對齊的數字看起來不錯。如果你覺得這看起來不錯(我不知道),你也可以填充前導零(字符'0',而不是數字0)。
在任何情況下,我們有「4」捲走安全。再次環回div
(首先使edx
爲零!)。現在我們在eax
中有12個,在edx
中有3個。對3做些什麼,然後再回到div
。 1在eax
和2在edx
。同樣,和eax
爲零(edx
爲1) - 在這一點上,我們就大功告成了!如果我們將eax
與9比較,我們可以跳過最後的div
--如果它較少,我們可以從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
無論如何,應該給你一些工作。玩的開心! :)
非常感謝弗蘭克。非常全面。 – Progrmr
http://www.dreamincode.net/forums/topic/202395-masm-adding-numbers/ –
當我嘗試使用'nasm -f elf -g -F stabs'進行編譯時,它會顯示'error :符號dwtoa undefined'。那麼這個位於nasm的'dwtoa'在哪裏? – Progrmr
http://forum.nasm.us/index.php?topic=1042.0 –