我被困在一个实践问题,我需要一个整数读,把它加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 –