2

我正在尝试编写一个简单的汇编应用程序,它从用户那里读取字符,然后检查输入的字符串是否可以被视为整数。

mov       ebx,esp
input:
get_ch    eax
cmp       eax,0dh
je        continue
push      eax
jmp       input

continue:
put_str    0ah

xor       edx,edx
output:

这就是我迷路的地方...

put_ch    dword ptr [ebx-4][edx]
dec       edx
jmp       output

...使用 [ebx-4] 和 edx = 0,我可以输出第一个字符。之后,它似乎正在输出空格或空字符。

任何帮助或参考链接将不胜感激,我很难找到可以查找 MASM 的东西。

4

2 回答 2

1

1) 我不熟悉 put_ch 或 get_ch,但我认为 put_ch dword ptr [ebx-4][edx] 在 EBX 和 EDX 调用之间需要一个“,”。

2) 每次迭代都将 EDX 更改为 -1,但指针 (EBX) 始终位于 ebx-4。如果我错了,请纠正我,但你不应该改变EBX吗?我不认为 -4 在每次迭代运行中实际上都会从 EBX 中减去。

3)我认为如果你从 0 中减去,就像你在 EBX 中所做的那样,在汇编中你只设置溢出标志(OF),或者至少设置 SF(符号标志)。检查您正在使用的 ASM 实现的标志,并查看哪些命令设置了哪些标志。

于 2014-01-23T19:43:18.753 回答
0

在我看来,您不必要地从输出循环的有效地址中减去 4。也许您认为括号用于乘法。不是这种情况; IA-32 不支持这种类型的寻址。在您的代码中,您将...

put_ch    dword ptr [ebx-4][edx]
dec       edx
jmp       output

在循环的第一次迭代的第一条指令中,作为 *put_ch* 宏的有效地址,相对于堆栈帧 (EBX) 的顶部为 -4。这个数字,代表堆栈上的地址,将被传递给宏以成功打印 ASCII 代码。但是,由于dec edx指令,第二次迭代将失败,因为程序将调用 *put_ch* 并使用参数 -5。由于这个地址的双字几乎毫无疑问会包含 0,*put_ch* 会将它注册为 NULL 字符,表示字符串的结束。尝试这个:

dec       edx
put_ch    dword ptr [ebx][edx*4]
jmp       output

在这里,EDX 首先递减并在宏中用作要乘以四的索引。因此,传递给 *put_ch* 的第一个地址将是 -4。传递的第二个地址是-8。第三个是-12,依此类推...

最后,我强烈建议,在比较 get_ch 的返回值和 0dh(回车)时,请使用 AL(1 字节)而不是 EAX(4 字节),以防 EAX 的高 3 字节包含任意数据。

祝你好运。

于 2014-01-26T22:01:47.053 回答