问题描述
这实际上是我今天针对这个特定问题的第二个问题,但是另一个问题很快得到了回答。
从本质上讲,我试图输入一串字母(没有数字或符号),然后将每个输入的字母与代表北约军事语音字母(Alpha,Bravo,查理(Charlie)等人),并输出与该信件等效的代表军事。
这就是我被困住的地方。我对Assembly来说还很陌生,这是一项家庭作业,因此非常需要帮助。我的教授不太擅长提供学习这些知识的资源,而且很难找到在线解决具体问题的良好资源。
任何帮助将不胜感激。特别是关于如何比较输入到数组的每个字母。我已经成功地将输入存储在变量中。
下面是我正在尝试做的C#表示。
.asciz
编辑:
因此,我相信这应该可以完成我想做的事情,但是它似乎没有按预期的方式工作。它在调试器中比较正确的东西,但是当它要打印数组的各个部分时,它根本不打印任何内容。
class MilAlpha
{
static void Main(string[] args)
{
string input;
string[] miliAlpha = { "Alpha","Beta","Charlie","Delta","Echo","Foxtrot","Golf","Hotel","India","Juliet","Kilo","Lima","Mike","November","Oscar","Papa","Quebec","Romeo","Sierra","Tango","Uniform","Victor","Whiskey","X-Ray","Yankee","Zulu" };
Console.WriteLine("Enter a string of text: ");
input = Console.ReadLine();
for (int i = 0; i < input.Length; i++) {
for (int j = 0; j < miliAlpha.Length; j++) {
if (input[i] == ' ')
Console.WriteLine("\n")
string temp = miliAlpha[j].ToLower();
if (input[i] == temp[0])
Console.WriteLine("\n" + miliAlpha[j] + "\n");
}
}
Console.ReadKey();
}
}
解决方法
有一些错误可以帮助您入门:
-
在
Loop
中,您将指针保持在%eax
中的输入字符串,但是将字符加载到%al
中,这是{{1}的低字节},从而破坏其价值。为其中之一选择另一个寄存器。 -
您永远不会在
%eax
中增加指针,因此它将永远循环(如果由于您的其他错误之一而导致指针没有首先崩溃)。 -
Loop
不会在连续调用中重置CompareAlpha
。因此,如果第一个字符是%edi
,则通话后'H'
将指向%edi
。如果下一个字符是"Hotel"
,则E
将从CompareAlpha
开始向前搜索。当然,它不会找到它,因此它会在数组末尾运行并崩溃。 -
"Hotel"
将字符串的四个字节加载到PrintWord
中(覆盖系统调用号),而应该将字符串的地址加载到%eax
中。将%ecx
替换为movl (%edi),%eax
(请注意,这是一次寄存器到寄存器的移动,而不是从内存中加载)。 -
movl %edi,%ecx
Clobbers寄存器PrintWord
,其调用者希望其中的一些保持不变。按下并弹出这些寄存器,或者在调用之前重写%eax,%ebx,%ecx,%edx
来完成此操作。 -
CompareAlpha
最后缺少一个PrintWord
,因此掉入了ret
。
修复这些问题后,我能够成功转换字符串ExitProg
。
所有这些都可以通过单步执行"HELLO"
调试器(gdb
命令)中的代码并观察寄存器(si
)的内容及其指向的内容({{ 1}}等)。我建议练习这个。
请注意,一种更有效的设计,而不是通过代码字数组进行线性搜索,将是简单地对其进行索引。取出您的字符并减去display $eax
(0x41)的ASCII码,乘以display/s $edi
,然后加到'A'
。现在,您有了一个无需循环的指向所需代码字的指针。如果像your other post中那样使用辅助指针数组,这将更加容易,因为每个指针的长度为4,因此您可以使用SIB寻址模式并执行$ElementLen
;确保$MAlpha
的高24位为零。这也避免了用空格填充所有代码字的麻烦(尽管那样,您将需要编写自己的movl MAlpha(,%eax,4),%edi
来计算长度,或者具有单独的长度数组,或者一次写出一个字节)直到最后看到0。
此外,作为一个一般性提示,记录每个子例程也是明智的:它到底做了什么,期望在哪个寄存器中输入并保留其输出,而哪个寄存器中有内容呢?您可能想尝试在两者之间具有一些共同点,甚至可能创建自己的标准调用约定。