2016-10-20 29 views
0

我想学习使用x86架构的大会。我可以做基本的计算,比如add,sub,mul,imul,div和idiv。但是,当我尝试打印结果时,字符串中有几个空格。有没有办法去除这些额外的空间?我目前正试图通过循环一个字符串并将非空格字符发送到第二个字符串来删除它们。如果这是这样做的,为什么我的代码不工作?我读了一些关于交换(xchg)的地方,但我不完全确定如何使用它。这会是一种更高效的方式吗?大会x86 Win32

   dtoa  product, eax  ; convert to ASCII characters 
       dtoa  xStart, x 
       dtoa  yContinue, y 
       lea  edi, product 
       mov  ecx, 20h   ; mov hex value of space into ecx 

forStart:  cmp  [edi], ecx  ; compare edi to space 
       jne  addToString 
       add  edi, 4   ; get address of next array element 
       cmp  [edi], 00h  ; cmp value of edi to null 
       je  printResult 
       jmp  forStart   ; loop through for next element 

addToString: mov  ecx, [edi]  ; mov value of edi into ecx 
       add  edi, 4   ; get address of next array element 
       cmp  [edi], 00h  ; cmp value of edi to null 
       je  printResult 
       jmp  forStart   ; loop through for next element 

printResult: output resultLbl, xStart ; output result 

回答

-1

这是相当不完整的。 dtoa不是x86指令,因此很难说出它的作用(可能是字符串转换例程的一些小数,但它究竟产生了什么以及它的工作原理是没有它的源代码或适当的文档而是神秘的)。

product声明丢失,也没有记录它是什么。

而且你也没有为你定义什么是“字符串”。

所有这些都是重要的,因为这样的代码,你做的事:

   mov  ecx, 20h   ; mov hex value of space into ecx 
forStart:  cmp  [edi], ecx  ; compare edi to space 
       jne  addToString 

(顺便说一句,你可以写第一个为mov ecx,' '

cmp [edi],ecx将比较DWORD值' ',所以你使用字符串的UTF-32编码?如果使用经典的ASCII编码,则必须仅比较BYTE(cmp [edi],cl),并且只能前进1(add edi,1)。

cmp [edi], 00h - >不清楚比较大小的值,使用一些大小说明符,如NASM中的cmp [edi], BYTE 00h

addToString你提取4个字节的字符串,但我没有看到你“添加”它,所以你什么也没做。再次使用4字节的元素对于UTF-32编码是有效的,但不知何故,我怀疑你使用的是ASCII零终止的字符串,所以你应该使用字节来代替?

这其中大部分可以在调试器想通了,如果你通过指令一步的指示,并采取概念在寄存器中的值如何变化,看在有趣的地址存储内容槽内存视图(其中edi点扫描期间' ',等等)。并与指导参考指南对抗,确保您了解每条指令的工作原理。

所以这个问题显示缺乏努力(调试)+要求调试。

最后你的问题(S)本身:

您的代码不正是按照您写的,即。完全无关你的“将非空格字符发送到第二个字符串”的初衷,代码甚至不接近它。

为什么你写不相关的代码..很难说,可能你应该尝试打破你原来的意图,甚至更简单的子任务(英文评论),并保持在你实施简单的子带有指令的步骤,以便您可以在调试期间比较CPU中发生的情况与原始意图。

xchg交换两个值。当然,如果你理解字符串是如何存储在内存中的,并且你希望与哪个值交换(取决于你的意图是什么),甚至可以使用这样的指令来处理字符串操作。

会有更有效的方法吗?

很难说,我甚至不知道你想达到什么目的。如果它像“电流输出:____30”(_是空格),“想要的输出:30”,那么您实际上不需要修改字符串,只需计算最初的空格字符并给出“输出”子程序即可xStart + <space_count>地址,所以它不会遇到包含空格的字节。或者可能有一些dtoa的配置,或者您的库中有一些其他功能,如C printf,您可以在其中轻松指定确切的格式。


编辑:“很难说”强调:

你保持代码的注释往往是无用的,甚至是错误的。

addToString: mov  ecx, [edi]  ; mov value of edi into ecx 

首先,它不移动的edi值成ecx,但存储器内容值在edi,这是致命的差所指向的地址。

其次,你明确指出,那就是指令的作用。你还是归档你的“人类意图”的评论,即:

addToString: mov  ecx, [edi]  ; reading 4 ASCII letters of string into ecx 

如果你想做到这一点,它会更容易地指出,你的人的意图熄灭时相比,在执行指令,并将你的思想水平错误指向你。

因为它可能只是写出工作代码而不是你,但是你是否会理解它为什么如此不同以及它是如何工作的......所以它需要你很多的努力(理解它)真正帮助你。而且你表现出缺乏努力 - 没有意义提供工作示例。