汇编:循环遍历一串字符并交换它们
Assembly: loop through a sequence of characters and swap them
我的任务是在汇编中实现一个函数,该函数将执行以下操作:循环遍历一个字符序列并交换它们,使最终结果是原始字符串的反转(100分)提示:从用户处收集字符串作为C-string,然后将其与用户输入的字符数一起传递给汇编函数。使用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;
}
你没有注释你的代码,所以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
EAX每一步都随着EDI的增长而增长,并且EDI呈线性增长。所以EAX呈几何级数增长(积分(x * dx) = x^2)
在调试器中单步执行应该很容易发现这个问题。
顺便说一句,正常的方法是一个指针向上走,一个指针向下走,当它们交叉时退出循环。那么你不需要单独的计数器,只需要cmp / ja
。(不要检查JNE或JE,因为它们可以相互交叉而不相等。)
总的来说,从字符串的两端开始交换元素直到到达中间是正确的想法。但是实现很糟糕。
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
指向当前要交换的符号。几乎可以,但这是惨败!每隔一秒的循环迭代都会使用错误的指针!这就是你的问题的根源。如果您使用指针而不是索引,或者使用偏移地址[eax+edi]
/[eax+esi]
...
交换部分可以
cmp edi, esi
je allDone
第二个退出条件,这次比较的是索引冲突!一般来说,一个退出条件就足够了;一些退出条件通常要么是多余的,要么暗示了算法中的一些缺陷。而且相等性比较是不够的——索引可以在单次迭代中从edi<esi
移动到edi>esi
。
- C++为一串单词添加空格
- 为什么Visual Studio正在清除我的一串反斜杠
- 如何将内存中的位转换为一串和零?
- 如何返回一串字母数字字符中的最大值(例如-1A003B3)?
- 将单个字符串/字符输入串行监视器
- 创建一个程序,该程序将一串数字作为输入,并输出偶数和奇数的总和
- C++ 如何对一串数字求平均值
- 从网络数据包复制一串 wchar 时访问冲突
- C - 将文本文件读为一串单词,然后将字符串分为向量
- 我如何在一串随机生成的字母I C 中查找一个单词
- 从一串数字C++创建一个数字序列
- 将一串十六进制存储到字符中
- 在另一个字符串中查找一串数字
- 将一串数字分解为26以下数字的计数方法
- 把一串单词解析成一组单词
- 使用算术记数法横向排列一串字符
- 我有编译器的情况。当我运行代码来去除一串特殊字符时,它在一个编译器中运行,但在另一个编译器中不运行?
- 编写一个程序,读取一串包含标点符号的字符,并写入被读取的内容,但删除了标点符号
- 汇编:循环遍历一串字符并交换它们
- 一串只允许字母用于矩形名称的第一个字符