为什么这个汇编程序会输出相同的字符串两次?

2023-12-11

此凯撒密码程序生成解密字符串(长度始终为 10)并输出为 output.txt 文件。 例如下面的代码创建 .txt 文件,

ILIKEASSEM

HOWAREYOUU

但是当我运行这段代码时,该文件是

ILIKEASSEM

ILIKEASSEM

即使通过 Visual Studio 2017 (MASM) 调试器 (T.T) 进行调试,我也不知道出了什么问题

怎么了...?

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

你溢出了12字节buffer 甚至之前开始外循环的第二次迭代L1。您破译这 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么这个汇编程序会输出相同的字符串两次? 的相关文章

  • 为什么我的空循环在 Intel Skylake CPU 上作为函数调用时运行速度是原来的两倍?

    我正在运行一些测试来比较 C 和 Java 并遇到了一些有趣的事情 在 main 调用的函数中 而不是在 main 本身中 运行具有优化级别 1 O1 的完全相同的基准代码 导致性能大约翻倍 我正在打印 test t 的大小 以毫无疑问地验
  • 大会,你好世界问题

    我正在 Linux 上学习 asm noobuntu 10 04 我得到了以下代码 http asm sourceforge net intro hello html http asm sourceforge net intro hello
  • “mov (%ebx,%eax,4),%eax”如何工作? [复制]

    这个问题在这里已经有答案了 一直在从事装配作业 并且在很大程度上我对装配非常了解 或者至少对于这项任务来说足够好 但这个 mov 的声明让我很困惑 如果有人能解释这个 mov 语句如何操作寄存器值 我将非常感激 mov ebx eax 4
  • 阴影空间示例

    EDIT 我接受了下面的答案 并添加了我自己的代码的最终修订版 希望它向人们展示影子空间分配的实际示例 而不是更多的文字 编辑 2 我还设法在 YouTube 视频 所有内容 的注释中找到了一个调用约定 PDF 的链接 其中有一些关于 Li
  • 如何使用movntdqa避免缓存污染?

    我正在尝试编写一个 memcpy 函数 该函数不会将源内存加载到 CPU 缓存中 目的是避免缓存污染 下面的 memcpy 函数可以工作 但会像标准 memcpy 一样污染缓存 我正在使用带有 Visual C 2008 Express 的
  • 设置 IRQ 映射

    我正在遵循一些教程和参考文献来尝试设置我的内核 我在教程中遇到了一些不熟悉的代码 但根本没有解释它 这是我被告知映射的代码16 IRQs 0 15 到 ISR 地点32 47 void irq remap void outportb 0x2
  • linux x86 汇编语言 sys_read 调用的第一个参数应为 0 (stdin)

    我正在编写一个简单的汇编程序来从标准输入读取 如 scanf 这是我的代码 section bss num resb 5 section txt global start start mov eax 3 sys read mov ebx 0
  • X86 预取优化:“计算 goto”线程代码

    我有一个相当重要的问题 我的计算图有循环和多个 计算路径 我没有制作一个调度程序循环 其中每个顶点将被一一调用 而是将所有预先分配的 框架对象 放置在堆中 代码 数据 这有点类似于线程代码 甚至更好 CPS 只是在堆中跳转 执行代码 每个代
  • 如何在程序中将自己缝合到自己的尾部,无限循环地封装 64KB 代码段?

    如果指令的顺序执行经过偏移量 65535 则8086将从同一代码段中的偏移量 0 处获取下一个指令字节 接下来的 COM 程序利用这一事实 不断将其整个代码 总共 32 个字节 缝合到自己的尾部 环绕在 64KB 代码段中 你可以称之为二元
  • 如何仅使用单个数组在 JavaScript 中模拟调用堆栈

    我正在看维基百科页面 https en wikipedia org wiki Call stack在调用堆栈上 并尝试理解这个图像 据我所知 哈哈 const memory memory 0 3 top of stack pointer m
  • 是否可以在VM内使用VMX CPU指令?

    VM guest 内部的进程是否有可能使用 VMX AMD V VT x CPU 指令 然后由外部 VMM 处理而不是直接在 CPU 上处理 Edit 假设外部VM使用VMX本身来管理其虚拟客户机 即它在Ring 1中运行 如果可能的话 是
  • Visual Studio 2012 本机 C++ DLL x86 编译

    我最近将我的工具集从 Win 7 x86 Visual Studio 2010 升级到 Win 8 x64 Visual Studio 2012 但是 现在我的本机 C dll 编译为 x64 而不是 x86 除了将代码移至新操作系统并将其
  • 在 x86 程序集中存储大量布尔值的最佳方法是什么?

    最近我一直在处理充满布尔值的大型数组 目前 我将它们存储在 bss部分有一个 space指令 它允许我创建字节数组 但是 由于我只需要存储布尔值 因此我希望从数组中逐位读取和写入数据 目前 我能想到的最好方法是有一个 space指令所需存储
  • 如何使用 Bochs 运行汇编代码?

    我想使用 Bochs 作为 8086 模拟器 是否有捷径可寻 我想要的是类似 emu8086 的东西 http www emu8086 com http www emu8086 com 如果程序的初始部分适合 512 字节 并且您不介意将自
  • 错误 LNK2019:函数 main 中引用的外部符号无法解析

    我正在尝试在 C 中运行我的简单汇编代码 我只有两个文件 cpp 文件和 asm 文件 编译时出现错误 见下文 如果有人可以提供帮助 我将不胜感激 这是我的 main cpp 文件 include
  • NASM 中的 equ 和 db 有什么区别?

    len equ 2 len db 2 它们是否相同 产生可以用来代替的标签2 如果不是 那么每种申报表的优点或缺点是什么 它们可以互换使用吗 第一个是equate 与 C 类似 define len 2 因为它实际上并没有在最终代码中分配任
  • 避免 gcc 函数序言开销?

    我最近遇到了很多 gcc 在 x86 上生成非常糟糕的代码的函数 它们都符合以下模式 if some condition do something really simple and return else something comple
  • 整数溢出问题

    我不断遇到整数溢出问题 我不知道如何解决它 有人可以帮忙吗 edx 包含 181 eax 包含 174 xor eax edx mov edx 2 div edx 假设你谈论的是x86 div edx这实际上没有意义 32位div将edx
  • 英特尔的最后分支记录功能是英特尔处理器独有的吗?

    最后分支记录是指存储与最近执行的分支相关的源地址和目标地址的寄存器对 MSR 的集合 它们受英特尔酷睿 2 英特尔至强和英特尔凌动处理器系列的支持 http css csail mit edu 6 858 2012 readings ia3
  • Grub 和进入实模式(低级汇编语言编程)

    我一直在开发一个玩具操作系统 并一直使用 grub 作为我的引导加载程序 最近尝试使用 VGA 时 我发现无法使用硬件中断 我发现这是因为我被 grub 置于保护模式 有人知道如何在不删除 grub 的情况下回到实模式吗 如果您使用 GRU

随机推荐