标题:随心的Win32汇编作业本
取消只看楼主
随心
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:12
帖 子:2577
专家分:250
注 册:2007-8-12
得分:0 
论坛有问题,那两句话竟然没出来.在这里补上:

汇编指令不是重点,不懂就查手册.
流程的理解和功能的分解是关键.

天之道,利而不害。圣人之道,为而不争。信言不美,美言不信。善者不辩,辩者不善。知者不博,博者不知。
2008-09-11 00:43
随心
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:12
帖 子:2577
专家分:250
注 册:2007-8-12
得分:0 
学习汇编两天了:
有一点点感想,和一块学习的人分享
① 兴趣最重要
② 不要被汇编这个名词吓倒,其实不难,无非就是几个指令的组合
③ 不要局限于书本,多找代码看,找自己感兴趣的代码看
④ 多写,多问,多查,多总结

还有引用14楼的一句话(点睛之笔):
汇编指令不是重点,不懂就查手册.
流程的理解和功能的分解是关键.

天之道,利而不害。圣人之道,为而不争。信言不美,美言不信。善者不辩,辩者不善。知者不博,博者不知。
2008-09-11 01:20
随心
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:12
帖 子:2577
专家分:250
注 册:2007-8-12
得分:0 
第六个程序:好几天没写了,熟练一下
程序代码:
.386 
.model flat,stdcall 
option casemap:none 
include windows.inc 
include kernel32.inc 
includelib kernel32.lib 
include user32.inc 
includelib user32.lib 

.data 
MsgBoxCaption  db "我的Win32汇编",0 
MsgBoxText     db "Win32 Assembly is Great!",0 

.code 
start: 
invoke MessageBox, NULL, addr MsgBoxText, addr MsgBoxCaption, MB_OK 
invoke ExitProcess, NULL 
end start 


天之道,利而不害。圣人之道,为而不争。信言不美,美言不信。善者不辩,辩者不善。知者不博,博者不知。
2008-09-18 17:05
随心
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:12
帖 子:2577
专家分:250
注 册:2007-8-12
得分:0 
addr操作符与offset操作符的区别:
addr操作符把标号的地址传递给被调用的函数,只能用在invoke语句中
offset可以把标号地址赋给变量或寄存器
===========
addr不可以处理向前引用,offset则能。所谓向前引用是指:标号的定义是在invoke 语句之后,譬如在如下的例子:
invoke MessageBox,NULL, addr MsgBoxText,addr MsgBoxCaption,MB_OK

......

MsgBoxCaption db "我的Win32汇编",0
MsgBoxText db "Win32 Assembly is Great!",0
=========
addr可以处理局部变量而 offset 则不能。局部变量只是在运行时在堆栈中分配内存空间。而 offset 则是在编译时由编译器解释,这显然不能用offset 在运行时来分配内存空间。编译器对 addr 的处理是先检查处理的是全局还是局部变量,若是全局变量则把其地址放到目标文件中,这一点和 offset 相同,若是局部变量,就在执行 invoke 语句前产生如下指令序列:
lea eax, LocalVar
push eax
因为lea指令能够在运行时决定标号的有效地址,所以有了上述指令序列,就可以保证 invoke 的正确执行了。

天之道,利而不害。圣人之道,为而不争。信言不美,美言不信。善者不辩,辩者不善。知者不博,博者不知。
2008-09-18 17:11
随心
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:12
帖 子:2577
专家分:250
注 册:2007-8-12
得分:0 
回复 24# ONEPROBLEM 的帖子
在小问题中学习,顺便练习一下发贴

天之道,利而不害。圣人之道,为而不争。信言不美,美言不信。善者不辩,辩者不善。知者不博,博者不知。
2008-09-18 17:13
随心
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:12
帖 子:2577
专家分:250
注 册:2007-8-12
得分:0 
第七个程序:第一个窗口程序
程序代码:
.386 ;使用80386指令集
.model flat,stdcall    
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib

;WinMain函数声明
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

;======================数据段
.data
ClassName db "SimpleWinClass",0
AppName  db "我的汇编窗口",0

.data?
hInstance HINSTANCE ?    ;应用程序句柄
CommandLine LPSTR ?        ;保存命令行传入的参数
;==========================

;==========================代码段开始
.code
start:
    invoke GetModuleHandle, NULL    ;得到应用程序句柄
    mov    hInstance,eax
    
    invoke GetCommandLine            ;得到命令行参数 
    mov    CommandLine,eax
    
    ;调用主函数
    invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
    ;退出程序
    invoke ExitProcess,eax

;===================主过程=======================
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
    ;注册窗口样式 
    LOCAL wc:WNDCLASSEX
    LOCAL msg:MSG
    LOCAL hwnd:HWND
    mov   wc.cbSize,SIZEOF WNDCLASSEX
    mov   wc.style, CS_HREDRAW or CS_VREDRAW
    mov   wc.lpfnWndProc, OFFSET WndProc
    mov   wc.cbClsExtra,NULL
    mov   wc.cbWndExtra,NULL
    push  hInstance
    pop   wc.hInstance
    mov   wc.hbrBackground,COLOR_WINDOW+1
    mov   wc.lpszMenuName,NULL
    mov   wc.lpszClassName,OFFSET ClassName
    invoke LoadIcon,NULL,IDI_APPLICATION
    mov   wc.hIcon,eax
    mov   wc.hIconSm,eax
    invoke LoadCursor,NULL,IDC_ARROW
    mov   wc.hCursor,eax
    invoke RegisterClassEx, addr wc
    ;创建窗口
    INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
           WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
           CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
           hInst,NULL
    mov   hwnd,eax
    ;显示窗口
    invoke ShowWindow, hwnd,SW_SHOWNORMAL
    invoke UpdateWindow, hwnd
    ;进入消息循环
    .WHILE TRUE
        invoke GetMessage, ADDR msg,NULL,0,0
        .BREAK .IF (!eax)
        invoke TranslateMessage, ADDR msg
        invoke DispatchMessage, ADDR msg
    .ENDW
    mov     eax,msg.wParam
    ret
WinMain endp

;回调函数
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    .IF uMsg==WM_DESTROY ;关闭消息 
        invoke PostQuitMessage,NULL
    .ELSE
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam    ;调用系统默认的函数进行处理    
        ret
    .ENDIF
    xor eax,eax
    ret
WndProc endp
end start


天之道,利而不害。圣人之道,为而不争。信言不美,美言不信。善者不辩,辩者不善。知者不博,博者不知。
2008-09-18 17:29
随心
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:12
帖 子:2577
专家分:250
注 册:2007-8-12
得分:0 
第八个程序:在窗口上输出文字
文字是输出了,只不过狂闪不已,汗一下...
在汇编中,我不会用rc文件
程序代码:
.386 ;使用80386指令集
.model flat,stdcall    
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
include gdi32.inc
includelib gdi32.lib

;WinMain函数声明
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

;======================数据段
.data
ClassName db "SimpleWinClass",0
AppName  db "我的汇编窗口",0
MyString db "我的第二个窗口程序",0

.data?
hInstance HINSTANCE ?    ;应用程序句柄
CommandLine LPSTR ?        ;保存命令行传入的参数
hdc HDC ?
;==========================

;==========================代码段开始
.code
start:
    invoke GetModuleHandle, NULL    ;得到应用程序句柄
    mov    hInstance,eax
    
    invoke GetCommandLine            ;得到命令行参数 
    mov    CommandLine,eax
    
    ;调用主函数
    invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
    ;退出程序
    invoke ExitProcess,eax

;===================主过程=======================
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
    ;注册窗口样式 
    LOCAL wc:WNDCLASSEX
    LOCAL msg:MSG
    LOCAL hwnd:HWND
    mov   wc.cbSize,SIZEOF WNDCLASSEX
    mov   wc.style, CS_HREDRAW or CS_VREDRAW
    mov   wc.lpfnWndProc, OFFSET WndProc
    mov   wc.cbClsExtra,NULL
    mov   wc.cbWndExtra,NULL
    push  hInstance
    pop   wc.hInstance
    mov   wc.hbrBackground,COLOR_WINDOW+1
    mov   wc.lpszMenuName,NULL
    mov   wc.lpszClassName,OFFSET ClassName
    invoke LoadIcon,NULL,IDI_APPLICATION
    mov   wc.hIcon,eax
    mov   wc.hIconSm,eax
    invoke LoadCursor,NULL,IDC_ARROW
    mov   wc.hCursor,eax
    invoke RegisterClassEx, addr wc
    ;创建窗口
    INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
           WS_SYSMENU or WS_MINIMIZEBOX,CW_USEDEFAULT,\
           CW_USEDEFAULT,200,200,NULL,NULL,\
           hInst,NULL
    mov   hwnd,eax
    ;显示窗口
    invoke ShowWindow, hwnd,SW_SHOWNORMAL
    invoke UpdateWindow, hwnd
    invoke GetDC, hwnd
    mov hdc, eax
    ;进入消息循环
    .WHILE TRUE
        invoke GetMessage, ADDR msg,NULL,0,0
        .BREAK .IF (!eax)
        invoke TranslateMessage, ADDR msg
        invoke DispatchMessage, ADDR msg
    .ENDW
    mov     eax,msg.wParam
    ret
WinMain endp

;回调函数
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    .IF uMsg==WM_DESTROY ;关闭消息 
        invoke PostQuitMessage,NULL
    .ELSEIF uMsg==WM_PAINT
        invoke TextOut, hdc, 0, 0, addr MyString, SIZEOF MyString
    .ELSE
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam    ;调用系统默认的函数进行处理    
        ret
    .ENDIF
    xor eax,eax
    ret
WndProc endp
end start

天之道,利而不害。圣人之道,为而不争。信言不美,美言不信。善者不辩,辩者不善。知者不博,博者不知。
2008-09-19 03:29
随心
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:12
帖 子:2577
专家分:250
注 册:2007-8-12
得分:0 
第八个程序第二版:解决不闪的问题
解决办法都在注释里了
程序代码:
.386 ;使用80386指令集
.model flat,stdcall    
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
include gdi32.inc
includelib gdi32.lib

;WinMain函数声明
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

;======================数据段
.data
ClassName db "SimpleWinClass",0
AppName  db "我的汇编窗口",0
MyString db "我的第二个窗口程序",0

.data?
hInstance HINSTANCE ?    ;应用程序句柄
CommandLine LPSTR ?        ;保存命令行传入的参数
;hdc HDC ?
;==========================

;==========================代码段开始
.code
start:
    invoke GetModuleHandle, NULL    ;得到应用程序句柄
    mov    hInstance,eax
    
    invoke GetCommandLine            ;得到命令行参数 
    mov    CommandLine,eax
    
    ;调用主函数
    invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
    ;退出程序
    invoke ExitProcess,eax

;===================主过程=======================
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
    ;注册窗口样式 
    LOCAL wc:WNDCLASSEX
    LOCAL msg:MSG
    LOCAL hwnd:HWND
    mov   wc.cbSize,SIZEOF WNDCLASSEX
    mov   wc.style, CS_HREDRAW or CS_VREDRAW
    mov   wc.lpfnWndProc, OFFSET WndProc
    mov   wc.cbClsExtra,NULL
    mov   wc.cbWndExtra,NULL
    push  hInstance
    pop   wc.hInstance
    mov   wc.hbrBackground,COLOR_WINDOW+1
    mov   wc.lpszMenuName,NULL
    mov   wc.lpszClassName,OFFSET ClassName
    invoke LoadIcon,NULL,IDI_APPLICATION
    mov   wc.hIcon,eax
    mov   wc.hIconSm,eax
    invoke LoadCursor,NULL,IDC_ARROW
    mov   wc.hCursor,eax
    invoke RegisterClassEx, addr wc
    ;创建窗口
    INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
           WS_SYSMENU or WS_MINIMIZEBOX,CW_USEDEFAULT,\
           CW_USEDEFAULT,200,200,NULL,NULL,\
           hInst,NULL
    mov   hwnd,eax
    ;显示窗口
    invoke ShowWindow, hwnd,SW_SHOWNORMAL
    invoke UpdateWindow, hwnd
    
    ;狂闪的原因:在这里得到了DC
   ; invoke GetDC, hwnd
    ;mov hdc, eax
    ;进入消息循环
    .WHILE TRUE
        invoke GetMessage, ADDR msg,NULL,0,0
        .BREAK .IF (!eax)
        invoke TranslateMessage, ADDR msg
        invoke DispatchMessage, ADDR msg
    .ENDW
    mov     eax,msg.wParam
    ret
WinMain endp

;回调函数
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
      LOCAL hdc:HDC 
    LOCAL ps:PAINTSTRUCT 
    .IF uMsg==WM_DESTROY ;关闭消息 
        invoke PostQuitMessage,NULL
    .ELSEIF uMsg==WM_PAINT
        invoke BeginPaint,hWnd, addr ps ;在这里得到DC就不闪了
        mov    hdc,eax 
        invoke TextOut, hdc, 0, 0, addr MyString, SIZEOF MyString
    .ELSE
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam    ;调用系统默认的函数进行处理    
        ret
    .ENDIF
    xor eax,eax
    ret
WndProc endp
end start

天之道,利而不害。圣人之道,为而不争。信言不美,美言不信。善者不辩,辩者不善。知者不博,博者不知。
2008-09-19 03:54
随心
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:12
帖 子:2577
专家分:250
注 册:2007-8-12
得分:0 
第九个程序:得到当前系统日期
程序代码:
.386 ;使用80386指令集
.model flat,stdcall    
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
include gdi32.inc
includelib gdi32.lib

;WinMain函数声明
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

;======================数据段
.data
ClassName db "SimpleWinClass",0
AppName  db "我的汇编窗口",0
MyString db "我的第二个窗口程序",0
Date_Format   db   "yyyy年MM月dd日",0     ;日期格式_1  

.data?
hInstance HINSTANCE ?    ;应用程序句柄
CommandLine LPSTR ?        ;保存命令行传入的参数
;hdc HDC ?
;==========================

;==========================代码段开始
.code
start:
    invoke GetModuleHandle, NULL    ;得到应用程序句柄
    mov    hInstance,eax
    
    invoke GetCommandLine            ;得到命令行参数 
    mov    CommandLine,eax
    
    ;调用主函数
    invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
    ;退出程序
    invoke ExitProcess,eax

;===================主过程=======================
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
    ;注册窗口样式 
    LOCAL wc:WNDCLASSEX
    LOCAL msg:MSG
    LOCAL hwnd:HWND
    mov   wc.cbSize,SIZEOF WNDCLASSEX
    mov   wc.style, CS_HREDRAW or CS_VREDRAW
    mov   wc.lpfnWndProc, OFFSET WndProc
    mov   wc.cbClsExtra,NULL
    mov   wc.cbWndExtra,NULL
    push  hInstance
    pop   wc.hInstance
    mov   wc.hbrBackground,COLOR_WINDOW+1
    mov   wc.lpszMenuName,NULL
    mov   wc.lpszClassName,OFFSET ClassName
    invoke LoadIcon,NULL,IDI_APPLICATION
    mov   wc.hIcon,eax
    mov   wc.hIconSm,eax
    invoke LoadCursor,NULL,IDC_ARROW
    mov   wc.hCursor,eax
    invoke RegisterClassEx, addr wc
    ;创建窗口
    INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
           WS_SYSMENU or WS_MINIMIZEBOX,CW_USEDEFAULT,\
           CW_USEDEFAULT,200,200,NULL,NULL,\
           hInst,NULL
    mov   hwnd,eax
    ;显示窗口
    invoke ShowWindow, hwnd,SW_SHOWNORMAL
    invoke UpdateWindow, hwnd
    
    ;狂闪的原因:在这里得到了DC
   ; invoke GetDC, hwnd
    ;mov hdc, eax
    ;进入消息循环
    .WHILE TRUE
        invoke GetMessage, ADDR msg,NULL,0,0
        .BREAK .IF (!eax)
        invoke TranslateMessage, ADDR msg
        invoke DispatchMessage, ADDR msg
    .ENDW
    mov     eax,msg.wParam
    ret
WinMain endp

;回调函数
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
      LOCAL hdc:HDC 
    LOCAL ps:PAINTSTRUCT 
    local   TimeStruct:SYSTEMTIME         ;时间结构   
    local   ShowDateStr[128]:byte         ;显示日期缓冲区 
    
    .IF uMsg==WM_DESTROY ;关闭消息 
        invoke PostQuitMessage,NULL
    .ELSEIF uMsg==WM_PAINT
        invoke BeginPaint,hWnd, addr ps ;在这里得到DC就不闪了
        mov    hdc,eax 

          invoke   GetSystemTime,addr   TimeStruct   

         invoke   GetDateFormat,NULL,0,addr TimeStruct, addr Date_Format, addr ShowDateStr,sizeof ShowDateStr       
        invoke TextOut, hdc, 40, 50, addr ShowDateStr, 14
    .ELSE
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam    ;调用系统默认的函数进行处理    
        ret
    .ENDIF
    xor eax,eax
    ret
WndProc endp
end start

天之道,利而不害。圣人之道,为而不争。信言不美,美言不信。善者不辩,辩者不善。知者不博,博者不知。
2008-09-19 04:07
随心
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:12
帖 子:2577
专家分:250
注 册:2007-8-12
得分:0 
终于温习了一下汇编,估计又得好几天没时间学习了

天之道,利而不害。圣人之道,为而不争。信言不美,美言不信。善者不辩,辩者不善。知者不博,博者不知。
2008-09-19 04:15



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-232219-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.116882 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved