- memory/
- Memory Assembly-尝试反转字符串,但会在最后一个字符串上添加一个额外字符
Memory Assembly-尝试反转字符串,但会在最后一个字符串上添加一个额外字符
Memory Assembly-尝试反转字符串,但会在最后一个字符串上添加一个额外字符,memory,assembly,loops,stack,masm,Memory,Assembly,Loops,Stack,Masm,我对汇编(老实说,一般来说是编程)相当陌生。我在试着玩这个堆栈。
此代码的用途:
输入一个字符串,限制为80个字符
重新打印输入的字符串
将每个字符推送到堆栈时打印
打印从堆栈中弹出的每个字符
打印反向字符串
代码在最后一步失败。
如果输入的字符串为“Help”,则会打印出“pleHe”。最后一个字符串中的最后一个字符是原始字符串的第二个字符
请帮我看看我把事情搞砸了
.data
buffer WORD 81 DUP(0)
byteCount WORD ?
.code
main PROC
我对汇编(老实说,一般来说是编程)相当陌生。我在试着玩这个堆栈。
此代码的用途:
- 输入一个字符串,限制为80个字符
- 重新打印输入的字符串
- 将每个字符推送到堆栈时打印
- 打印从堆栈中弹出的每个字符
- 打印反向字符串
代码在最后一步失败。
如果输入的字符串为“Help”,则会打印出“pleHe”。最后一个字符串中的最后一个字符是原始字符串的第二个字符
请帮我看看我把事情搞砸了
.data
buffer WORD 81 DUP(0)
byteCount WORD ?
.code
main PROC
call Clrscr ;Clear screen
RS:
mov edx, OFFSET buffer ;Move String to edx
mov cl, [SIZEOF buffer]-1 ;Set loop counter to (size of buffer) -1
call ReadString ;Read a User's String
mov byteCount, ax ;Move the size of User's String to byteCount
cmp byteCount, 80 ;Compare byteCount with 80
ja RS ;If byteCount is greater then 80, ask for another String
call WriteString ;Write User's String to screen
call Crlf ;New Line
call reverseIt ;Reverse order of String
exit
reverseIt PROC
movzx ecx, byteCount ;Set Loop1 Counter to size of String
mov esi, 0 ;Zero out ESI
L1: ;Loop1 - Pushes String into Stack one character at a time
movzx eax, buffer[esi] ;Dereference buffer and place in eax
call Crlf ;New Line
call WriteChar ;Print current character to screen
push eax ;Push current character to stack
inc esi ;Move to next character
loop L1
call Crlf
movzx ecx, byteCount ;Set Loop2 Counter to size of String
mov esi, 0 ;Zero out ESI
L2: ;Loop2 - Pops Characters back into String in reverse order
pop eax ;Retrieve character from top of stack
call Crlf ;New Line
call WriteChar ;Print current character to screen
mov buffer[esi], ax ;Writes character to String
inc esi ;Increase esi
loop L2
call Crlf ;New Line
call Crlf ;New Line
mov edx, OFFSET buffer ;Move String to edx for WriteString
call WriteString ;Prints String to Screen
call Crlf ;New Line
ret ;Return to main
reverseIt ENDP
main ENDP
END main
.数据
缓冲字81 DUP(0)
字节数字?
.代码
主进程
调用CLRSC;清屏
卢比:
mov-edx,偏移缓冲器;将字符串移动到edx
mov-cl,[SIZEOF-buffer]-1;将循环计数器设置为(缓冲区大小)-1
调用ReadString;读取用户的字符串
mov字节数,ax;将用户字符串的大小移动到字节计数
cmp字节数,80;将字节数与80进行比较
ja RS;如果字节数大于80,则请求另一个字符串
通话记录;将用户字符串写入屏幕
调用Crlf;新线
调用反转;字符串的倒序
出口
反转过程
movzx-ecx,字节数;将Loop1计数器设置为字符串的大小
movesi,0;零出ESI
L1:;Loop1-将字符串一次推入堆栈中一个字符
movzx-eax,缓冲区[esi];取消引用缓冲区并放置在eax中
调用Crlf;新线
呼叫WriteChar;将当前字符打印到屏幕
推动eax;将当前字符推送到堆栈
公司esi;移动到下一个角色
回路L1
呼叫Crlf
movzx-ecx,字节数;将Loop2计数器设置为字符串的大小
movesi,0;零出ESI
L2:;Loop2-按相反顺序将字符弹出回字符串
pop-eax;从堆栈顶部检索字符
调用Crlf;新线
呼叫WriteChar;将当前字符打印到屏幕
mov缓冲器[esi],ax;将字符写入字符串
公司esi;增加esi
回路L2
调用Crlf;新线
调用Crlf;新线
mov-edx,偏移缓冲器;将字符串移动到edx以进行WriteString
通话记录;将字符串打印到屏幕上
调用Crlf;新线
ret;返回main
反向ENDP
主端
结束主问题问题
您将ASCII字符视为单词而不是字节,因此一次只能反转两个字符:
当您一次反转字符串两个字符时,您最终会将这些值写入缓冲区:
esi+0: p-
esi+1: lp
esi+2: el
esi+3: He
在每次迭代过程中,缓冲区如下所示:
Help--
p-lp--
plpp--
plel--
pleHe-
因此,您最终会将额外的e写入缓冲区。我想e不会出现在你的WriteChar循环中
解决方案
我尚未测试您的代码,因此无法确定,但您似乎需要更改这一行:
mov buffer[esi], ax ;Writes character to String
到
也许改变这一行也是个好主意:
buffer WORD 81 DUP(0)
因此它使用字节:
buffer BYTE 81 DUP(0)
谢谢你!我知道我使用的是单词而不是字节,因为第一部分限制了字符串的大小,而不是字节。它正把绳子从中间剪断。
所以我没有把缓冲区改成字节
这就是说,我尝试了另一个更改(我想我以前也尝试过),但不断得到一个编译错误,说明两个操作数的大小必须相同
我通过将缓冲区[esi]转换为一个字节来修复这个问题!
现在它工作得很好!谢谢
mov byte ptr buffer[esi],al
使用反汇编程序逐步完成。尝试找出第二个“e”被添加到缓冲区的位置。正确的方法是将缓冲区声明为字节数组(现在您正在声明一个162字节-81*2的缓冲区)。我的猜测是,在调用ReadString
之后,您在ax
中得到一个无效的结果,要回答如何解决这个问题,您需要展示ReadString是如何实现的字节计数
也可以声明为字节
,因为单个字节可以保存字符串的最大值80
buffer BYTE 81 DUP(0)