繁体   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