您正在看的汇编语言是:hello,world!win32汇编小程序。
首先我们看一个“复杂”的Win32汇编程序
程序用来显示一个消息框
--------------------------------------------------
;文件名:3asm
386
model flat ,stdcall
NULL equ 0
MB_OK equ 0
ExitProcess PROTO :Dword
MessageBoxA PROTO :DWORD,:DWORD,:DWORD,:Dword
includelib kernel32lib
includelib user32lib
data
szText db "Hello, world!",0
szCaption db "Win32Asm",0
code
start:
push MB_OK
lea eax,szCaption
push eax
lea eax,szText
push eax
push NULL
call messageboxa
xor eax,eax
push eax
call exitprocess
end start
--------------------------------------------------
编译链接:
分下面两步进行:
ml /c /coff 3asm
link /subsystem:Windows /libpath:d:\masm7\lib 3obj
第一步编译生成3obj文件
/c 表示只编译,不链接
/coff 表示生成COFF格式的目标文件
第二步链接生成3exe文件
/subsystem:windows 表示生成Windows文件
/libpath:d:\masm7\lib 表示引入库的路径为:d:\masm7\lib。
在安装Masm32后,引入库位于Masm32\Lib目录下。
也可设置环境变量Lib的值:在dos提示符下键入Set Lib=d:\masm7\lib,这样“链接”就可简单写成:
link /subsystem:Windows 3obj,试想一下,在程序调试过程中,修改源程序是常用的事啦,每次编译链接都要带/libpath:那该有多烦人呢。当然,我们也可在源程序中直接给出引入库的位置,这样,链接时就方便啦,如下:
includelib d:\masm7\lib\kernel32lib
includelib d:\masm7\lib\user32lib
--------------------------------------------------
执行:在dos提示符下键入3,回车,出现一个消息框,哈哈,真正的Win32程序!
--------------------------------------------------
深入分析:
看一下源程序,有这么两行:call messageboxa\call exitprocess。大家一看都知道,这是子程序调用,但是我们并没写这样的子程序,事实上,这些是API函数。作为函数,我们在调用时可能需要传送给函数一些参数,程序怎么知道传送的参数有哪些,类型是什么呢?就是通过函数原型定义,如下所示:
ExitProcess PROTO :Dword
MessageBoxA PROTO :DWORD,:DWORD,:DWORD,:Dword
可以看出,ExitProcess有一个参数,MessageBoxA有四个参数,这些参数都是Dword类型。
在Win32中,参数的传递都是通过堆栈来完成的。象MessageBoxA这个函数有四个参数,究竟是左边的先压入堆栈还是右边的先入栈呢?model flat,stdcall给出了答案。stdcall 指定参数是从右到左压入堆栈的,且调整堆栈是在子程序返回时完成的。在源程序中不需要用“add sp,值”来保持堆栈平衡。对MessageBox,在API手册中是这样定义的:
int MessageBox(
HWND hWnd, // handle of owner window
LPCTSTR lpText, // address of text in message box
LPCTSTR lpCaption, // address of title of message box
UINT uType &n
您正在看的汇编语言是:hello,world!win32汇编小程序。
bsp; // style of message box
)
;所以会有我们的程序段:
push MB_OK
lea eax,szCaption
push eax
lea eax,szText
push eax
push NULL
call messageboxa
看看上面的程序,不难想到,假如在写程序时,少往堆栈里压入一个数据,那将是一个致命的错误。能不能将这种检查参数个数是否匹配的工作交给计算机来完成呢?这是可以的,INVOKE指令可以帮助我们完成这样的工作。假如你的参数个数不正确,连接器将给出错误提示。所以,极力建议你使用invoke代替call来调用子程序,当然,这不是绝对的。使用invoke上面的指令就可简写成下面的样子,看起来简炼多啦,查错也方便啦!
invoke messageboxa, NULL,addr szText,addr szCaption,MB_OK
另外,像NULL,MB_OK都是一些常量,这样的常量有很多,还有很多的结构,如果在我们的程序中一开始都写这么多的东西,可能一下子就把你吓怕啦,也容易出错,更不便于看程序的主要部分。hutch整理的Windowsinc包含了WIN32编程所需要的常量和结构体的定义,我们可简单的用一个include指令将这些常量和结构的定义插入到我们的文件中:
include d:\masm32\include\Windowsinc
但是Windowsinc中并不包含函数原型的声明,还要从其他的头文件中得到函数原型的声明,比如:messageboxa的原型声明在user32inc文件中,exitprocess在kernel32inc文件中。这些头文件都放在 \masm32\include文件夹下。
还有,要用Windowsinc,必须使用option casemap:none,它的意思是告诉 MASM 要区分符号的大小写,譬如:start和START是不一样的。否则,一个小小的程序,可能会出成百上千的错误呀!
其他的,就不再细说啦,到此,上面的程序可重新修改如下:
-----------------------------------------------------------------
;最终的结果
386 ;表示要用到386指令
model flat,stdcall ;32位程序,要用flat啦!;stadcall,标准调用
option casemap:none ;区别大小写
include Windowsinc ;包括常量及结构定义
include kernel32inc ;函数原型声明
include user32inc
includelib kernel32lib ;用到的引入库
includelib user32lib
data;数据区,定义2个字符串
szText db "Hello, world!",0
szCaption db "Win32Asm",0
code ;代码开始执行处
start:
invoke MessageBox,NULL,addr szText,addr szCaption,MB_OK
;调用MessageBoxAPI函数
invoke ExitProcess,NULL ;程序退出
end start;结束
------------------------------------
编译链接:
ml /c /coff /I d:\masm7\include 3asm ;注意开关符识别大小写
link /subsystem:Windows /libpath:d:\masm7\lib 3obj
/I d:\masm7\include 表示inc文件的位置,也可设置环境变量Set include=d:\masm7\include来简化 *** 作,也可在程序中明确指出inc的位置。
前面讲的都是用两条指令来完成编译链接,实际上用一条指令也可完成,如下:
ml /coff /I d:\masm7\include 3asm /link /subsystem:Windows /libpath:lib
若inc及引入库在源程序中都明确指出其位置,则可简化为:
ml /coff 3asm /link /subsystem:
win10装itunes提示安装汇编错误,解决办法:1将Windows Module Installer启动,启动方式为(win7):“我的电脑”右击——管理——服务和应用程序——服务——Windows Module Installer——右击启动。2若出现资源不够的提示,那是因为以前安装某些软件限制了注册表的大小。解决办法是在开始窗口输入regedit进入注册表。找到HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control。注意在选中Control的情况下,在右边选择RegistrySizeLimit(REG_DWORD类型),将其的值改为 FFFFFFFF (10进制就是 4294967295)重新启动计算机后启动Windows Module Installer。如果装过之前版本的iTunes,在重启之前确保所有的iTune启动项都打开,这样,就可以安装完成了。
据我所知,有编译器,反编译器至少现在还没有……
64为处理器结构根据官方资料X64多了8个通用寄存器:R8、R9、R10、R11、R12、R13、R14、R15,当然,它们都是64位的。
所以需要有专门针对这种新处理器结构的反汇编工具才能完成反汇编……
另外X32中原有的寄存器在X64中均为扩展为64位,且名称的第一个字母从E改为R。不过我们还是可以在64位程序中调用32位的寄存器,如RAX(64位)、EAX(低32)、AX(低16位)、AL(低8位)、AH(8到15位),相应的有R8、R8D、R8W和R8B。不过不要在程序中使用如AH之类的寄存器,因为在AMD的CPU上这种用法会与某些指令产生冲突。所以反汇编过程也更加复杂,相信各大编程论坛已经开始有高手尝试着去解决反汇编这类复杂的问题,我们一同关注吧……
DSEG SEGMENT
msgi db "please input a string:$";显示信息,提示输入一串字符
buf db 100,0,100 dup ();输入字符串缓冲区
digit db 100 dup ();数字字符缓冲区
leter db 100 dup ();字母字符缓冲区
other db 100 dup ();其它字符缓冲区
dn db ;数字字符个数
ln db ;字母字符个数
on db ;其它字符个数
msgd db 0dh,0ah,"digits are:$";显示信息,提示数字字符显示
msgl db 0dh,0ah,"leters are:$";显示信息,提示字母字符显示
msgo db 0dh,0ah,"others are:$";显示信息,提示其它字符显示
msgdn db 0dh,0ah,"digits:$";显示信息,提示数字字符个数显示
msgln db 0dh,0ah,"leter :$";显示信息,提示字母字符个数显示
msgon db 0dh,0ah,"other:$";显示信息,提示其它字符个数显示
DSEG ENDS
CSEG SEGMENT
assume cs:CSEG, ds:DSEG
MAIN PROC FAR ;主程序入口
mov ax, dseg
mov ds, ax
lea dx,msgi;显示信息,提示输入一串字符
mov ah,9
int 21h
lea dx,buf;输入字符串
mov ah,0ah
int 21h
lea si,buf
mov cl,[si+1];输入字符实际个数存入CX中
mov ch,0
add si,2;输入字符起始地址存入SI
lea bx,digit;数字字符起始地址存入BX
lea di,leter;字母字符起始地址存入DI
lea bp,other;其它字符起始地址存入BP
fenlei:
mov al,[si];取出一个字符
cmp al,30h;判断该字符是否为数字
jb oth
cmp al,39h
ja ulet
mov [bx],al;若为数字字符,则存入相应缓冲区
inc bx
inc dn;并将数字字符个数加1
jmp next
ulet:
cmp al,41h;判断该字符是否为大写字母
jb oth
cmp al,5ah
ja llet
mov [di],al;若为大写字母字符,则存入相应缓冲区
inc di
inc ln;并将字母字符个数加1
jmp next
llet:
cmp al,61h;判断该字符是否为小写字母
jb oth
cmp al,7ah
ja oth
mov [di],al;若为小写字母字符,则存入相应缓冲区
inc di
inc ln;并将字母字符个数加1
jmp next
oth:
mov ds:[bp],al;为其它字符,则存入相应缓冲区
inc bp
inc on;并将其它字符个数加1
next:
inc si;调整地址,指向下一个字符
loop fenlei;循环次数为实际输入字符个数
mov byte ptr [bx],'$';在数字字符串末尾加'$',目的用9号中断显示该串
mov byte ptr [di],'$';在字母字符串末尾加'$',目的用9号中断显示该串
mov byte ptr ds:[bp],'$';在其它字符串末尾加'$',目的用9号中断显示该串
lea dx,msgd;显示数字字符
mov ah,9
int 21h
lea dx,digit
mov ah,9
int 21h
lea dx,msgl;显示字母字符
mov ah,9
int 21h
lea dx,leter
mov ah,9
int 21h
lea dx,msgo;显示其它字符
mov ah,9
int 21h
lea dx,other
mov ah,9
int 21h
lea dx,msgln;显示数字字符个数
mov ah,9
int 21h
mov bl,dn
call disp;以十进制形式显示个数
lea dx,msgln;显示字母字符个数
mov ah,9
int 21h
mov bl,ln
call disp
lea dx,msgon;显示其它字符个数
mov ah,9
int 21h
mov bl,on
call disp
mov ah,1;按任意键退出
int 21h
mov ax, 4c00h ;程序结束,返回到 *** 作系统系统
int 21h
MAIN ENDP
disp proc near
mov ch,2
rotate:
mov cl,4
rol bl,cl
mov al,bl
and al,0fh
add al,30h
cmp al,3ah
jl printit
add al,7h
printit:
mov dl,al
mov ah,2
int 21h
dec ch
jnz rotate
ret
disp endp
CSEG ENDS
END MAIN
以上就是关于用汇编语言编写一个小程序(比如hello,word!)请懂的人帮忙提供源码全部的内容,包括:用汇编语言编写一个小程序(比如hello,word!)请懂的人帮忙提供源码、Win10 64位系统,安装itunes总是出现汇编错误(如图)、有没有64位程序的资源编译/反编译工具,例如32位下面的eXeSCOPE等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)