⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 用masmplus学习win32汇编(2) .txt

📁 会变语言实现的一些程序
💻 TXT
字号:
用MasmPlus学习Win32汇编(2) 
    作者:Zoologist 于2007-9-16上传   

--------------------------------------------------------------------------------
  控制台,就是Windows下面那个黑色的窗口。进入控制台有两种方式,一种是运行 Command.com:



  另一种是运行 Cmd.exe:



   这两种方式上存在一些差别… …我们要运行Win32 Console程序,建议选择后者。之所以要介绍这种就是因为很轻松的看到结果。

一.第一个console程序

  MasmPlus已经为我们准备好了模板:新建

  

  选择Masm工程标签页:

  

  选中 “Win32 Console”确定即可。我们将它存为Console1.asm之后出现的这个模板本身就是一个可以编译通过的小程序,加载之后我们立即就可以运行看到结果。

  

  按下回车即结束。在保存目录下,我们可以看到编译生成了的 console.exe 文件。(可以尝试一下从运行 cmd 或者 command 先进入dos box 再进入这个目录运行 console 看看结果有什么不同)

  下面我们对这个简单的程序进行一下的分析:

  invoke StdOut,CTXT("Hello World!")  
  ;StdOut 并不是Windows的API,而我暂时找不到Aogo把Macro藏到什么地方了
  ;所以就不讲述了,知道后面跟着字符串的地址就可以了


  invoke StdIn,addr buffer,sizeof buffer 

  ;暂停显示,回车键关闭
  ;同样,这个我也不解释了,输入的应该是ascii码,存放在前面定义的buffer中

  invoke ExitProcess,0
  ;这个就是退出结束的意思。

  修改,输入,然后显示输入:

  invoke StdIn,addr buffer,sizeof buffer   
  invoke StdOut,addr buffer
  invoke ExitProcess,0

  编译运行程序会一闪而过,但是如果你在dos box下面看就能看到整个过程。

二.Ascii码
  我发现实际上很多人无法理解Ascii 十六进制 二进制 ……这些乱其八糟的东西,在这里我觉得有必要讲述一下。
  ASCII 全称是 American Standard Code for Information Interchange美国信息交换标准码。起始于50年代后期,在1967年定案。ASCII 码使用指定的 7 位或 8 位二进制数组合来表示 128 或 256 种可能的字符。一般情况下我们使用的是8位的。一个字节也是8位的,因此正好能够将它们按照数字对字符一一对应起来。

  比如: mov al,25h (注意,是十六进制的25h) 然后将 al 直接输出,结果就是“%”。这就是简单的对应。额外的:

  十六进制 显示出来的字符
  30h                0 
  31h                1 
  32h                2 
  33h                3 
  34h                4 
  35h                5 
  36h                6 
  37h                7 
  38h                8 
  39h                9 

  就是说 mov al,31h 显示出来就是 “1”。如果还不明白,不妨动手实验下面的程序:(注意:.data 不是 .data? 字符串放在后者显示不出来)


.386
.model flat, stdcall
option casemap :none

include windows.inc
include user32.inc
include kernel32.inc
include masm32.inc

includelib user32.lib
includelib kernel32.lib
includelib masm32.lib
include macro.asm

.data
   buffer   db 31h,32h,33h,34h,35h,36h,37h,38h,0
.CODE
START:

   invoke StdOut,addr buffer
   invoke ExitProcess,0

end START


  需要注意的是不是所有的Ascii都是可见的,因此我们直接用记事本打开一个可执行文件时会看到很多乱码,比如我们使用记事本打开 D:\MASMPlus\Bin\CVTRES.exe 结果如下:

  

  而使用十六进制编辑软件ultraEdit打开这个文件,看到的就是:

   

  左边是按照十六进制表示的,右边是左边数值对应的Ascii,很多无法显示的Ascii都用“.”来表示了。可以看出来和用Notepad打开的看起来很“像”。

  观察上面那个十六进制对Ascii的表可以发现一点点“规律”,一个数字 N 加上30h之后显示出来就是这个数字。如果我们要按照十六进制显示 AL中的数值,就可以将Al的高4位加上30h显示一下,再按照同样的方式处理低4位。不过 0-9的数值和A-F的并不连续,这里需要特殊处理一下。下面的dos程序段就是这个原理(非常不幸的是Dos Box中,我们的conole程序无法直接调用int 21h).


;Input AL,Bl,No Output
ShowAL proc
             pusha
              mov  dl,al      ;保存AL
              mov  cl,04       
              shr  al,cl      ;AL高4位移至低4位
              mov  cx,02h     ;循环2次

Low4bit:     cmp  al,09
              jbe  larger     ;低4位超过9
              add  al,07
larger:      add  al,30h

              push  cx
             mov  bh,0h
             mov  cx,1h
              mov  ah,09h
              int  10h
              pop  cx
              
             add  shX,1
             call SetCur
             mov  al,dl      ;恢复保存
               and  al,0Fh
              loop  Low4bit
              popa
         ret
ShowAL   endp


  如果有兴趣的话,可以将这个程序改造为你自己的console的showal.

  另外,有些书上说 一个字节(Byte)是9位(bit),这样的说法中多出来的这一位是奇偶校验位,是硬件上使用的,对我们软件来说是透明的。我教过一个人编写DDR2内存检测软件,需要找出内存哪个芯片坏了,他写的程序就使用了9位,我在查看他代码的时候觉得非常崩溃,他委屈的说这是从网上查到的......

三.更简单的解决方法

  上面是典型的DOS时代的思想:了解原理,同硬件做最亲密的接触。但是,用小刀在硬盘上刻操作系统的时代已经过去了... ...上网搜索一下,有一个API wsprintf,原型请参考API手册或MSDN,或直接在线查看:http://msdn2.microsoft.com/en-us/library/ms647550.aspx

  试验一下:

.386
.model flat, stdcall
option casemap :none

include windows.inc
include user32.inc
include kernel32.inc
include masm32.inc

includelib user32.lib
includelib kernel32.lib
includelib masm32.lib
include macro.asm

.data?
   buffer   db 100 dup(?)
   lpszSize   db 50 dup(?)
   
.CODE
START:
   
   mov eax,1235
   invoke wsprintf,offset lpszSize,CTXT("%d"),eax 
;将EAX 按照Signed decimal integer格式化,然后放到 
;lpszSize中
   invoke StdOut, offset lpszSize
   
   ;暂停显示,回车键关闭
   invoke StdIn,addr buffer,sizeof buffer
   invoke ExitProcess,0
   
end START


  运行结果:

  

  (之后建议读者试验一下如何使用此API显示十六进制)

三. WinExec

  上面的内容可能让人觉得乏味,下面就介绍1个好玩的API。WinExec ,原型请参考API手册或MSDN,或直接在线查看:http://msdn2.microsoft.com/en-us/library/ms687393.aspx

  试验一下:


.386
.model flat, stdcall
option casemap :none

include windows.inc
include user32.inc
include kernel32.inc
include masm32.inc

includelib user32.lib
includelib kernel32.lib
includelib masm32.lib
include macro.asm

.data
   szCmdline   db   '\windows\notepad.exe',0
.data?
   buffer   db 100 dup(?)
   
.CODE
START:
   
   invoke StdOut,CTXT("I will run a program...")
    invoke WinExec,ADDR szCmdline,SW_SHOWNORMAL
   invoke StdIn,addr buffer,sizeof buffer
   invoke ExitProcess,0
   
end START


  

  前面提到,可以添加参数,我们可以实验一下

  szCmdline   db   '\windows\notepad.exe c:\boot.ini',0

  另外,还可以实验一下返回值,看看错误的情况下返回值是多少。

  掌握了控制台的输入输出方式,我们就可以很容易的验证一些API,很容易的就能看到结果。

--------------------------------------------------------------------------------
<<<上一篇  欢迎访问AoGo汇编小站:http://www.aogosoft.com 下一篇>>>  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -