daimagogo 2023-05-28 18:25 采纳率: 57.1%
浏览 12
已结题

汇编语言masm32

img


想了几天写不出来,这个汇编语言的顺序结构设计,在masm32编辑器,求解

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-05-28 23:26
    关注
    • 这篇文章讲的很详细,请看:win32汇编以.386指令的MASM32题目做题记录 -- 循环结构
    • 除此之外, 这篇博客: masm32 汇编hello world程序中的 我的第一个masm32 汇编程序 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
    • 个人笔记本配置win8系统,intel core i5 cpu。

      一、masm32的安装
       官网DownLoad masm32一路下来,安装到D盘根目录下即可。

      二、配置环境变量(用户变量)
      include  ==>> D:\masm32\include
      lib  ==>> D:\masm32\lib
      path  ==>> D:\masm32\bin

      三、写一个汇编代码保存为D:\masm32\hello.asm

      .386
      .model flat,stdcall
      option casemap:none
      include kernel32.inc
      includelib kernel32.lib
      include masm32.inc
      includelib masm32.lib
      
      .data
          hello db "hello world" ;如果用str代替hello会报错
      .code
         
      start:    
          push offset hello
          call StdOut      ;调用显示函数 大小写不能错       
          ;int 21h ;此方法运行程序时报错
          ;mov ah,01 ;此方法运行程序时报错
          ;int 21h   ;此方法运行程序时报错
      exit:             
          push 0
          call ExitProcess
      end start
      

      四、编译并执行
       控制台编译程序

      在这里插入图片描述五、程序执行效果
      点击工具栏命令行按钮快速打开cmd界面在这里插入图片描述运行hello.exe 显示输出hello world在这里插入图片描述

    • 以下回答由chatgpt基于相关博客总结生成:

      根据问题描述,该问题的主要难点在于如何优化顺序结构的设计,具体地说,如何在设计顺序结构时提高代码的执行效率和减小代码的体积。针对该问题,可以从以下两个方面进行优化:

      1. 代码执行效率的优化

      在设计顺序结构时,应该优先考虑如何提高代码的执行效率。具体来说,可以采用以下几种方法:

      (1)尽可能使用寄存器

      寄存器是CPU中的一种高速存储器件,可以大幅提高代码的执行速度。因此,在编写汇编代码时,应该尽可能地使用寄存器,减少对内存的访问次数。例如,在处理大型数组时,可以将数组的地址存到寄存器中,从而减少内存访问次数。

      (2)使用循环和跳转语句

      循环和跳转语句可以大幅降低代码的执行次数,从而提高程序的执行效率。在设计顺序结构时,可以使用循环和跳转语句来减少重复代码的出现,从而提高代码的效率。

      (3)使用宏定义和函数封装

      在编写较长的汇编程序时,可以采用宏定义、函数封装等方式来减少代码的重复,并提高代码的重用性。例如,可以将一些常用的操作封装为函数,然后通过调用函数的方式来实现功能,从而减少重复代码的出现。

      1. 代码体积的优化

      除了代码执行效率,代码体积的大小也是设计顺序结构时需要考虑的重要问题。具体来说,可以采用以下几种方法:

      (1)使用MOVZX和MOVZB等指令

      MOVZX和MOVZB等指令可以将数据从一个寄存器或内存地址传递到另一个寄存器中,并在传递的同时把高位置为0。这种指令可以有效地减少代码的体积,提高程序的执行效率。

      (2)使用变量的首次引用

      在引用一个变量时,需要指定变量的存储地址。如果在后续的代码中重复引用同一变量,可以省略原来的指令,直接使用变量的首次引用进行引用。例如,可以使用LEA指令将数组的首地址存储到一个寄存器中,并在后续的代码中直接使用寄存器来引用数组。

      (3)使用指令的别名

      汇编指令有许多别名,可以在语句中使用这些别名来减少代码的长度。例如,MOV AX,0可以使用XOR AX,AX等代码替代。

      参考代码:

      下面是汇编程序的优化版本,其中采用了寄存器存储和循环跳转等方式来提高代码的执行效率,同时采用了MOVZX和MOVZB等指令以及指令的别名等方式来减小代码的体积:

      .386 .model flat, stdcall option casemap:none include D:\masm32\include\windows.inc include D:\masm32\include\kernel32.inc include D:\masm32\include\masm32.inc includelib D:\masm32\lib\kernel32.lib includelib D:\masm32\lib\masm32.lib include D:\masm32\include\user32.inc includelib D:\masm32\lib\user32.lib ExitProcess PROTO, dwEXITCODE: DWORD

      .data ;待处理文件绝对路径 path BYTE "C:\Users\Em1ya\Desktop\Re\NOTE.exe",0

      ;存放待处理文件的句柄 filehandle DWORD ?

      ;以下数据全为显示字符,没有实际含义 str0 BYTE " ",0 str1 BYTE "IMAGE_DOS_HEADER:",0 str2 BYTE "IMAGE_NT_HEADER:",0 str3 BYTE "IMAGE_FILE_HEADE:",0 str4 BYTE "IMAGE_OPTIONAL_HEADER:",0 str5 BYTE "e_magic:",0 str6 BYTE "e_lfanew:",0 str7 BYTE "Signature:",0 str8 BYTE "NumberOfSections:",0 str9 BYTE "TimeDateStamp:",0 stra BYTE "Characteristic:",0 strb BYTE "AddressOfEntryPoint:",0 strc BYTE "ImageBase:",0 strd BYTE "SectionAligment:",0 stre BYTE "FileAligment:",0 strn BYTE 0ah,00h

      filebuf BYTE 4000 DUP(0) filebase DWORD ? var DWORD ?

      ;下面声明的是把十六进制值转为字符串输出的函数 Print PROTO stdcall:DWORD,:DWORD

      .code Print PROC res:DWORD,hexdw:DWORD ;参数res待写缓冲区,hexdw待转换十六进制值 ;edi指向待转换的值,ecx为循环变量,eax指向待写的缓冲区字符串 MOV ecx,8h MOV eax,res ;循环将最高位保留做与运算,拿到最低位作为索引在table里面拿值 L2: MOV ebx,hexdw AND ebx,0f0000000h SHR ebx,28 MOV DL,BYTE PTR [table+EBX] MOV BYTE PTR[eax],dl INC eax SHL hexdw,4 LOOP L2

      ;输出
      INVOKE StdOut, res
      ret
      

      Print ENDP

      main PROC ;通过路径得到句柄,打开程序和文件的联系->通过句柄得到指向文件的指针->通过句柄读取文件内容->关闭文件和程序的连接 INVOKE CreateFile,addr path,\ GENERIC_READ,\ FILE_SHARE_READ,\ 0,\ OPEN_EXISTING,\ FILE_ATTRIBUTE_ARCHIVE,\ 0 MOV filehandle,eax INVOKE SetFilePointer, filehandle,\ 0,\ 0,\ FILE_BEGIN INVOKE ReadFile, filehandle,\ addr filebuf,\ 3900,\ 0,\ 0 MOV esi,OFFSET filebuf MOV ecx,10d ;以下操作将文件的内容写到了filebuf,之后读取filebuf就可以拿到PE文件的内容 ;以下所有,esi为目标量在内存中的地址,eax为该地址对应值,print函数把eax传入,输出对应8-t个字符串 L1:
      TEST ecx,ecx JZ L999 MOV EAX,DWORD PTR [esi] TEST ecx,1 JZ L2 MOVZX EAX,WORD PTR [esi] L2: INVOKE Print,addr Res,\ eax INVOKE StdOut,addr strn ADD esi,4 DEC ecx JMP L1

      L999: INVOKE CloseHandle,filehandle INVOKE ExitProcess,0 main ENDP END main

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 6月1日
  • 创建了问题 5月28日

悬赏问题

  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 有没有帮写代码做实验仿真的
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥30 vmware exsi重置后登不上
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容
  • ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题
  • ¥20 yolov5自定义Prune报错,如何解决?