现如今是高级语言的天下,现在人很少提及汇编这种低级语言,今天有学妹问我汇编好学不?我举了个简单的例子,做一个窗口化的程序,就是简单地一个“Hello World”,以下是运行结果,很简单的一个程序,很多人却对汇编望而却步
下面是代码,开发环境是 Notepad++(强化的记事本)+ MASM 32
.386
.model flat, stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; IncludeFile Direct
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include gdi32.inc
includelib gdi32.lib
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; DataSegment
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hWinMain dd ?
.const
szClassName db 'MyClass',0
szCaptionMain db 'This is a Window Test!',0
szTest db 'Hello World ! ',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Code Segment
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Windows Main
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain proc uses ebx ediesi,hWnd,uMsg,wParam,lParam
LOCAL @stPs:PAINTSTRUCT
LOCAL @stRect:RECT
LOCAL @hDc
mov eax,uMsg
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.if eax== WM_PAINT
invoke BeginPaint,hWnd,addr @stPs
mov @hDc, eax
invoke GetClientRect,hWnd,addr @stRect
invoke DrawText,@hDc,addr szTest, -1,addr @stRect,DT_SINGLELINE or DT_CENTER or DT_VCENTER
invoke EndPaint,hWnd,addr @stPs
;*****************************************************************
.elseif eax == WM_CLOSE
invoke DestroyWindow,hWinMain
invoke PostQuitMessage,NULL
;*****************************************************************
.else
invokeDefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
;*****************************************************************
xor eax, eax
ret
_ProcWinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain proc
LOCAL @stWndClass:WNDCLASSEX
LOCAL @stMsg:MSG
invoke GetModuleHandle,NULL
mov hInstance, eax
invoke RtlZeroMemory,addr@stWndClass,sizeof @stWndClass
;*****************************************************************
; Windows Registing
;*****************************************************************
invoke LoadCursor,0,IDC_ARROW
mov @stWndClass.hCursor, eax
push hInstance
pop @stWndClass.hInstance
mov @stWndClass.cbSize, sizeof WNDCLASSEX
mov @stWndClass.style, CS_HREDRAW or CS_VREDRAW
mov @stWndClass.lpfnWndProc, offset _ProcWinMain
mov @stWndClass.hbrBackground, COLOR_WINDOW + 1
mov @stWndClass.lpszClassName, offset szClassName
invoke RegisterClassEx,addr@stWndClass
;*****************************************************************
; Bulid and Show Windows
;*****************************************************************
invoke CreateWindowEx,WS_EX_CLIENTEDGE,\
offset szClassName , offsetszCaptionMain,WS_OVERLAPPEDWINDOW,\
100,100,600,400,NULL,NULL,hInstance,NULL
mov hWinMain, eax
invoke ShowWindow,hWinMain,SW_SHOWNORMAL
invoke UpdateWindow,hWinMain
;*****************************************************************
; Message Repeat
;*****************************************************************
.while TRUE
invoke GetMessage,addr @stMsg,NULL,0,0
.break .if eax == 0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.endw
ret
_WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
call _WinMain
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
使用Win32汇编开发程序并不是想象的那么复杂,直接使用Windows API 省时省力,但是问题在于需要了解更多的操作系统的知识,和对Windows 运行机制的深入理解,直接使用API编程带来的问题就是,很多东西,例如CPU寄存器管理,堆栈平衡,错误检查等一些本来由高级语言编译器完成的项目在汇编下不再透明,相比DOS实模式下的汇编,Win32保护模式下的汇编虽然有实用易懂的API接口,(这里只是一个相对的概念,比起DOS环境下那毫无规律冷冰冰的int,我现在依稀记得写DOS程序时需要一本厚厚的中断手册是怎么样的无奈,所以WindowsAPI的出现简直是福音),但是保护模式下的限制使得编程并不轻松,相比其他高级语言丰富的函数库编程的复杂度更高了。
汇编程序猿做梦都在羡慕其他程序猿比如C,C++,JAVA语言丰富的类库,在现如今各种高级语言充斥的今天,大红大紫的JAVA,还是新秀R语言,都使得汇编被遗弃到角落,成为“冷门技术”,就拿我们矿大优快云社团而论,我负责的组只有我一个人,我是名副其实的光杆司令,我所能说的是,“冷门”,不代表其没有价值,在底层开发,进程和文件分析,病毒和反病毒领域,怎能离得开汇编?
汇编揭开了平时隐藏在编译器和系统面纱下的程序运行机制,学习它,就算是粗略了解,也能对系统和程序有更深入的理解。
我记得一本书里说过,学汇编的就像高考,千军万马过独木桥,少有人挤过来,复杂困难使得很多人下马。
同时这也是一个孤独的旅途,需要无比的耐心和毅力,这个领域是给那些有毅力,能坚持的人。时刻保持自己的热忱,在孤独和寂寞中摸索,对于一个从事汇编,逆向等工作的人来说,或许个人心境和能力同样重要。
PS:当然我不是在自夸,我作为注定单身的矮矬穷,能从事底层为上层的高富帅们打下基础,也算是价值所在。