我的任务是在程序集中实现一个函数,该函数将执行以下操作: 循环遍历一系列字符并交换它们,使得最终结果是反向的原始字符串(100分) 提示:从用户收集字符串作为C字符串,然后将其与用户输入的字符数一起传递给汇编函数。要找出字符数,请使用strlen()函数。
我已经编写了c ++和汇编程序,并且它的工作范围很好:例如,如果我输入12345,输出正确显示为54321,但如果超过5个字符:输出开始不正确:对于例如,如果输入123456,则输出为:653241。我将非常感谢任何可以指出我的错误的人:
.code
_reverse PROC
push ebp
mov ebp,esp ;stack pointer to ebp
mov ebx,[ebp+8] ; address of first array element
mov ecx,[ebp+12] ; the number of elemets in array
mov eax,ebx
mov ebp,0 ;move 0 to base pointer
mov edx,0 ; set data register to 0
mov edi,0
Setup:
mov esi , ecx
shr ecx,1
add ecx,edx
dec esi
reverse:
cmp ebp , ecx
je allDone
mov edx, eax
add eax , edi
add edx , esi
Swap:
mov bl, [edx]
mov bh, [eax]
mov [edx],bh
mov [eax],bl
inc edi
dec esi
cmp edi, esi
je allDone
inc ebp
jmp reverse
allDone:
pop ebp ; pop ebp out of stack
ret ; retunr the value of eax
_reverse ENDP
END
这是我的c ++代码:
#include<iostream>
#include <string>
using namespace std;
extern"C"
char reverse(char*, int);
int main()
{
char str[64] = {NULL};
int lenght;
cout << " Please Enter the text you want to reverse:";
cin >> str;
lenght = strlen(str);
reverse(str, lenght);
cout << " the reversed of the input is: " << str << endl;
}
答案 0 :(得分:3)
你没有评论你的代码,所以IDK到底想要做什么,但看起来你是用MOV / ADD手动进行数组索引而不是像[eax + edi]
那样使用寻址模式。
然而,看起来您正在修改原始值,然后以一种在未经修改的情况下有意义的方式使用它。
mov edx, eax ; EAX holds a pointer to the start of array, read every iter
add eax , edi ; modify the start of the array!!!
add edx , esi
Swap:
inc edi
dec esi
每一步都通过EDI增长EAX,EDI线性增长。所以EAX在几何上增加(整数(x * dx)= x ^ 2)。
在调试器中单步执行此操作应该很容易找到它。
顺便说一下,执行此操作的常规方法是向上移动一个指针,向下移动一个指针,并在它们交叉时从循环中掉出来。那么你不需要一个单独的计数器,只需cmp / ja
。 (不要检查JNE或JE,因为它们可以相互交叉而不平等。)
答案 1 :(得分:0)
总的来说,你是正确的想法,从字符串和交换元素的两端开始,直到你到达中间。虽然实施很糟糕。
mov ebp,0 ;move 0 to base pointer
这似乎是循环计数器(评论无用甚至更糟);我想是交换length/2
元素,这是完全没问题的。我只是比较指针/索引,一旦碰撞就退出。
mov edx,0 ; set data register to 0
...
add ecx,edx
mov edx, eax
无用且误导。
mov edi,0
mov esi , ecx
dec esi
看起来像索引开始/结束字符串。好。我打算用指针开始/结束字符串;但索引也有效
cmp ebp , ecx
je allDone
如果长度/ 2次迭代,则退出。行。
mov edx, eax
add eax , edi
add edx , esi
eax
和edx
指向要交换的当前符号。几乎可以,但这个clobbers eax !第二次后的每次循环迭代将使用错误的指针!这就是首先引起问题的原因。如果您使用指针代替索引,或者如果您使用偏移量寻址[eax+edi]
/ [eax+esi]
...
交换部分没问题
cmp edi, esi
je allDone
第二次退出条件,这次比较索引碰撞!通常一个退出条件就足够了;几个退出条件通常是多余的或暗示算法中的某些缺陷。同样的比较还不够 - 索引可以在单次迭代中从edi<esi
转到edi>esi
。