assembly - 为什么这个汇编程序两次输出相同的字符串?
问题描述
这个凯撒密码程序生成解密字符串(长度始终为 10),输出为 output.txt 文件。例如下面的代码生成 .txt 文件,
ILIKEASSEM
HOWAREYOUU
但是当我运行这段代码时,文件是
ILIKEASSEM
ILIKEASSEM
即使通过 Visual Studio 2017 (MASM) 调试器 (TT) 进行调试,我也不知道出了什么问题
怎么了...?
INCLUDE Irvine32.inc
.data
Num_Str DWORD 2
;;key = 10
Cipher_Str BYTE "SVSUOKCCOW",0
BYTE "RYGKBOIYEE",0
filename BYTE"output.txt", 0
fileHandle DWORD ?
BUFFER_SIZE = 12
buffer BYTE BUFFER_SIZE DUP(?)
L BYTE "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0
Decipher BYTE "QRSTUVWXYZABCDEFGHIJKLMNOP", 0
count DWORD ?
.code
main PROC
mov edx, OFFSET filename
call CreateOutputFile
mov fileHandle, eax
mov ecx, Num_Str
mov esi, 0
L1:
push ecx
mov ecx, 11
L2:
mov al, Cipher_Str[esi]
sub al, 65
movzx ax, al
movzx eax, ax
mov edi, eax
mov al, Decipher[edi]
mov buffer[esi], al
inc esi
loop L2
mov bl, 13
mov buffer[esi], bl
inc esi
mov bl, 10
mov buffer[esi], bl
mov eax,fileHandle
mov edx,OFFSET buffer
mov ecx, BUFFER_SIZE
call WriteToFile
pop ecx
loop L1
mov eax, fileHandle
call CloseFile
exit
main ENDP
END main
解决方案
甚至在开始外循环L1的第二次迭代之前,您就溢出了 12 字节缓冲区 。您破译这 10 个字符,还破译终止的零(您应该忽略它),然后添加回车和换行。总共有 13 个字节!
您进一步溢出它,因为您没有重置寄存器。ESI
一种可能的解决方案是在外循环的每次迭代中将索引输出缓冲区的偏移寄存器重置为零,并使用不同的索引寄存器来引用相隔 11 个字节的密码字符串。
BUFFER_SIZE = 12
...
mov esi, offset Cipher_Str
L1:
xor edi, edi ; EDI=0
L2:
movzx eax, byte ptr [esi+edi]
mov al, Decipher[eax-65]
mov buffer[edi], al
inc edi
cmp edi, 10
jb L2
mov word ptr buffer[edi], 0A0Dh
mov eax, fileHandle
mov edx, OFFSET buffer
mov ecx, BUFFER_SIZE
call WriteToFile
add esi, 11 ; Move to the 2nd input string (or after it)
cmp esi, offset Cipher_Str + 22
jb L1
推荐阅读
- sql - 如何在 SQL Query 的 where 子句中使用 LIKE,但 LIKE 的值会来自其他查询?
- c# - 使用 C# 将文件发送到打印机队列会忽略打印设置
- javascript - Wordpress Javascript注入不起作用
- laravel - 来自公共类助手的 Laravel 更新表不起作用
- powershell - 如何自动化我的 Powershell 脚本以对 www.vodafone.de 页面进行日常检查?
- c# - NLog 不记录调试消息
- mongodb - 使用 MongoDB 解码将字符串从 MongoDB 转换为 int
- asp.net-mvc - 如何从类型对象中获取属性和值?
- sql - SQL查询以计算最小日期范围和其他列中的日期
- amazon-web-services - AWS:如何创建 ELB 健康检查端点?