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

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(使用前将#替换为@)

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

  • 如何让 gcc 生成合适的代码来检查缓冲区是否充满 NUL 字节?

    我正在实现一个解析磁带档案的程序 解析器逻辑的一部分是检查存档结束标记 该标记是一个充满 NUL 字节的 512 字节块 我为此编写了以下代码 希望 gcc 能对此进行很好的优化 int is eof block const char us
  • 添加饱和 32 位有符号整数内在函数?

    有人可以推荐一种使用 Intel 内在函数 AVX SSE4 添加饱和 32 位有符号整数的快速方法吗 我查看了内在指南并发现 mm256 adds epi16但这似乎只添加 16 位整数 我没有看到 32 位有任何类似的东西 其他电话似乎
  • 返回地址预测堆栈缓冲区与堆栈存储的返回地址?

    一直在阅读 Agner Fog 的 Intel AMD 和 VIA CPU 的微架构 他在第 34 页描述了 返回地址预测 http www agner org optimize microarchitecture pdf http www
  • 是否可以调用驻留在 exe 中的非导出函数?

    我想调用驻留在第 3 方 exe 中的函数并获取其结果 好像有should是一种方法 只要我知道函数地址 调用约定等 但我不知道如何 有谁知道我会怎么做 我意识到任何解决方案都是非标准的黑客 但有must成为一种方式 我的非恶意用例 我正在
  • 段错误...关于你好世界

    这段代码非常简单 但我在 x86 64 Linux 系统上遇到了段错误 这让我很烦恼 刚开始接触asm 请耐心等待 与 NASM 组装nasm f elf64 test asm 与连接ld o test test o SECTION tex
  • 与 SSE 比较 16 字节字符串

    我有 16 字节的 字符串 它们可能更短 但您可能会假设它们在末尾用零填充 但您可能不会假设它们是 16 字节对齐的 至少不总是 如何编写一个例程将它们与 SSE 内在函数进行比较 是否相等 我发现这个代码片段可能会有帮助 但我不确定它是否
  • (nasm x86实模式)如何在引导加载的扇区中写入/读取字符串?

    我正在使用 NASM 为 x86 实模式编写一个最小操作系统 用于教育目的 我想使用 512 字节引导扇区加载包含操作系统其余部分的更大扇区 我已经成功创建了一个加载另一个扇区的引导扇区 但我似乎无法在加载的扇区中写入 读取字符串 这是我的
  • 在 x86 汇编语言中获取文件大小的简单方法

    假设我已经在汇编中打开了一个文件 并且在寄存器 eax 中有该文件的文件句柄 我将如何获取文件的大小 以便为其分配足够的缓冲区空间 我在这里研究了另一个讨论 建议使用sys fstat 28 系统调用来获取文件统计信息但无法实现它 My a
  • 内存映射图形输出

    我正在探索使用内存映射图形绘制像素和线条 我在 Windows 的 Textpad 中使用 TASM 当我单击 运行 时 整个屏幕变成蓝色 就是这样 没有绘制像素 model small stack data saveMode db xVa
  • __stack_chk_fail_local 和 -fno-stack-protector - 如何让它工作?

    Update 我刚刚发现问题出在我的项目 libxml2 中包含的预构建库上 它是在启用堆栈保护的情况下构建的 因此依赖于 stack chk fail local方法 我现在已经重建了该库 fno stack protector也是 一切
  • 查找用户输入中的第一个和最后一个大写字母

    输入将从 a z 或 A Z 中获取 并且输入以星号结束 我们需要将输入字符的第一个和最后一个大写字母作为输出 另外 我们应该显示每次输入的内容 注意 我们逐个字符地获取输入 而不是作为字符串 测试用例1 输入 aAbCcP 输出 AP 测
  • 将 1 字节立即值添加到 2 字节内存位置

    The add说明文档来 自这一页 http x86 renejeschke de html file module x86 id 5 html说如下 请注意我突出显示的两条说明 我在 NASM 中尝试了以下代码 符合第一个突出显示的指令
  • 如何从内存加载值而不污染缓存?

    我想读取内存位置而不污染缓存 我正在 X86 Linux 机器上工作 我尝试使用 MOVNTDQA 汇编指令 asm movntdqa source dest n t dest x my var source m my mem 0 memo
  • 将 AT&T 语法转换为 INTEL 语法

    我发现这个 GAS 文件包含一些可以从 CD 启动的引导加载程序代码 我想研究它并尝试制作我自己的一个 但唯一的问题是它采用 AT T 语法而不是 Intel 语法 我对 AT T 语法一无所知 我尝试过使用 Intel2gas 转换器 但
  • MFENCE/SFENCE/etc“序列化内存但不序列化指令执行”?

    英特尔系统编程指南第 8 3 节中有关 MFENCE SFENCE LFENCE 的说明 以下指令是内存排序指令 而不是序列化指令 这些指令会耗尽数据内存子系统 它们不序列化指令执行流 我试图弄清楚为什么这很重要 在多线程代码中 对内存的写
  • 使用非规范地址检索内存数据会导致 SIGSEGV 而不是 SIGBUS

    我无法使用以下汇编代码产生 总线错误 这里我使用的内存地址不是合法的 规范地址 那么 我怎样才能触发该错误呢 我在带有 NASM 2 14 02 的 Ubuntu 20 04 LTS 下运行这段代码 但它会导致负载出现 SIGSEGV 分段
  • 在汇编中初始化字符串数组

    我想创建一个数据数组 在初始化数据部分保存 5 个字符串 每个字符串正好有 4 个字符 每个字符串都有一些初始数据 例如第一个字符串的 abcd 第二个字符串的 efgh 等等 无效的 0任何字符串都不需要字符 如何用汇编语言初始化字符串数
  • Intel 上的 gcc 中的 _mm_pause 用法

    我参考过这个网页 https software intel com en us articles benefitting power and performance sleep loops https software intel com
  • Nasm 点状标签

    我对 TASM 很熟悉 但对 NASM 不太了解 我读过 NASM 允许使用本地标签 这些标签在名称前用点表示 例如 代码 loop some code jmp loop 定义一个名为 loop的局部标号 引用的地址在后面的jmp指令中使用
  • x86-64 AMD 上 CALL 指令的操作数生成

    以下是示例程序 objdump 的输出 080483b4

随机推荐