簡體   English   中英

Linux nasm匯編dwtoa

[英]linux nasm assembly dwtoa

我遇到了一個實際問題,我需要讀取一個整數,將其加1並打印出結果。 關於這個問題: linux nasm程序集打印從零到100的所有數字 ,用戶Gunner提到了dwtoa。 我假設這是一個可調用的函數。 那么,這個dwtoa函數是什么? 如果它實際上是一個可調用的函數,那么我在哪里可以得到它(我的意思是我該如何在我的代碼中實現它?)?

提前致謝。

好吧,你得寫...或借用別人已經寫好的東西。 后者更容易(C庫具有這樣的功能,並且很容易從asm調用),但是前者更“有趣”。 (如果您喜歡這種東西-嘿,有些人會填字游戲)

div指令非常慢。 有一種更好的方法是基於乘以倒數和“反向乘積”。 這很復雜。 我們將等待div :)

div ebx

如果我們安排在eax數字,例如1234,在ebx 10,則現在eax中將使用123, edx 4( ebx保持不變)。 實際上,我們想在div之前在edx設置0 ...

xor edx, edx

div ebx

如您所知,我們可以通過添加字符“ 0”(或48個十進制或30h)將數字4轉換為字符“ 4”。 現在我們有了可以打印的東西! 但是我們還沒有准備好打印它-我們正在使數字倒退。 有幾種方法可以解決此問題。 我認為最簡單的方法是將它們push堆棧,然后以正確的順序pop 另一種方法是繼續將它們放回緩沖區中,並在末尾進行“字符串反轉”。 另一種方法是從緩沖區的“末端”開始並朝前工作(在每個字符之后將索引減少到緩沖區中而不是遞增)。 這可能意味着當數字用完時,您還不太處於緩沖區的開頭。 我們可以利用它來發揮優勢-如果您要在列中打印'em',則正確的對正數字看起來會很好。 如果您認為看起來不錯(我也不喜歡),也可以用前導零填充(字符“ 0”,而不是數字0)。

無論如何,我們都會安全地藏匿“ 4”。 循環並再次div (首先使edx為零!)。 現在我們在eax有12個,在edx 3個。 對3進行處理,然后再次返回div eax 1,在edx 2。 同樣, eax為零( edx為1)-至此,我們完成了! 我們可以跳過最后div如果我們比較eax 9 -如果是少,我們可以從得到我們最終的(第一個將打印的)數字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 ;-------------- 

那個被剪切粘貼的“應該”工作。 它也可以改進。 使用一種“有趣的”方式乘以十,然后添加轉換為數字的新字符。 此時,程序的“工作”包括: add eax, 1無論如何應給您一些add eax, 1東西。 玩得開心! :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM