RadASM环境,win32汇编入门教程之十四

;运行效果

;RadASM环境,win32汇编入门教程之十四
;在这一教程里,我们来学一下基本的计算,加减乘除,这个起码要知道怎么表达出来。

.386 
.model flat,stdcall 
option casemap:none 

include    windows.inc 
include    user32.inc 
include    kernel32.inc
 
includelib user32.lib 
includelib kernel32.lib 

;EQU等值定义
IDB01      equ 101
IDB02      equ 102
IDB03      equ 103
IDB04      equ 104
IDB05      equ 105

ICO_MAIN   equ 1000    ;图标
;函数声明
DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD   ;对话框窗口函数

.data 
DlgName    db "MyDialog",0

szMsg      db "提示",0
szFrm01    db "计算结果是 %d",0
szFrm02    db "除法的结果商是 %d,余数是 %d",0
sz01       db "点击了第1个按钮",0
sz02       db "单击了第2个按钮",0
.data? 
hInstance HINSTANCE             ? 


.const 


.code 
start: 
         invoke GetModuleHandle, NULL 
         mov    hInstance,eax 
         invoke DialogBoxParam, hInstance, ADDR DlgName,NULL, addr DlgProc, NULL 
         invoke ExitProcess,eax 

DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM 
        LOCAL @szBuffer[256]:byte
        LOCAL @hico
        
        .if     uMsg == WM_INITDIALOG 
                invoke    LoadIcon,hInstance,ICO_MAIN
                mov @hico,eax    
            invoke    SendMessage,hWnd,WM_SETICON,ICON_SMALL,@hico
            invoke    SendMessage,hWnd,WM_SETICON,ICON_BIG,@hico
        .elseif uMsg == WM_COMMAND
            mov eax,wParam                 ;wParam的底位字节是标识符
            mov ebx,lParam              
            .if ax == IDB01                ;进行加法运算
                   mov eax,11
                   mov ebx,22
                   add eax,ebx             ;相当于eax+ebx,结果在eax           
                   invoke wsprintf,addr @szBuffer,addr szFrm01,eax
                       invoke MessageBox,NULL,addr @szBuffer,addr szMsg,MB_OK      
                .elseif ax == IDB02            ;进行减法运算
                       mov eax,22
                   mov ebx,11
                   sub eax,ebx                ;相当于eax-ebx,结果在eax
                   invoke wsprintf,addr @szBuffer,addr szFrm01,eax
                       invoke MessageBox,NULL,addr @szBuffer,addr szMsg,MB_ICONINFORMATION + MB_OK   
                .elseif ax == IDB03            ;进行乘法运算
                       mov eax,11
                   mov ebx,33
                   mul ebx                ;相当于eax*ebx,结果在eax
                   invoke wsprintf,addr @szBuffer,addr szFrm01,eax                
                       invoke MessageBox,NULL,addr @szBuffer,addr szMsg,MB_ICONINFORMATION + MB_OK 
                .elseif ax == IDB04            ;进行除法运算
                       mov edx,0             
                       mov eax,4294967295
                   mov ebx,11
                   div ebx                 ;相当于eax/ebx,商在eax,余数在edx
                   invoke wsprintf,addr @szBuffer,addr szFrm02,eax,edx
                       invoke MessageBox,NULL,addr @szBuffer,addr szMsg,MB_ICONINFORMATION + MB_OK 
                .elseif ax == IDB05            ;进行除法运算
                       mov edx,1             
                       mov eax,0
                   mov ebx,11
                   div ebx                 ;相当于eax/ebx,商在eax,余数在edx
                   invoke wsprintf,addr @szBuffer,addr szFrm02,eax,edx
                       invoke MessageBox,NULL,addr @szBuffer,addr szMsg,MB_ICONINFORMATION + MB_OK                        
                .endif      

        .elseif uMsg == WM_CLOSE 
                invoke EndDialog, hWnd,NULL 
        .else 
                mov eax,FALSE 
                ret 
        .endif 
                mov eax,TRUE 
        ret 
DlgProc endp 

end start 
;在上面的内容时,有标注了加减乘除法的方式
;这些计算都是无符号的计算,就是都是正数的计算。
;加法的指令是add,减法的是sub,乘法的是mul,除法的是div
;这里主要是要注意寄存器的容量。
;以前说过,比如al是单字节,最多为十六进制的FF,即最多为255,超过就不行。
;所以,我们给寄存器赋值时要考虑一下,使用的寄存器的最大值
;这里基本上都是使用eax或ebx之类的,是32位,即最大值可以十六进制的FFFFFFFF,也就是4294967295,所以很难超过这个值,一般不会出错
;最后一个是除法,你看这一句 mov ebx,11
;意思是除数是在ebx里面,而ebx是32位,根据除法的原则,除数是32位,那被除数应该是64位,被除数是除数的两倍容量,因为必须保证被除数大于除数
;当然,如果除数是16位,那么被除数就应该是32位,以此类推。
;好吧,如果你搞不清楚哪个是被除数,哪个是除数,这里的4294967295/11,4294967295就是被除数,11就是除数。

;你观察一下,4294967295是十进制值,转换为十六进制,那就是FFFFFFFF,每个字节最大的值是FF,这里是8个F,也就是只能装4个字节,而eax就是4个字节。
;这时候,被除数的低字节是eax,高字节是edx,简单地说,就是把edx和eax拼起来,可以装下更大的值。把edx和eax拼起来是系统规定,不能说我要把ebx和eax拼起来也行。
;假设被除数是4294967296,比eax可以装的最大值大1,转换成十六进制就是100000000,它比FFFFFFFF就多了1位,用eax就装不下了。
;我们可以试试,强行把4294967296赋值给eax,看会不会出错。

;那解决的办法是把用2个寄存器来装。
;这里,我们又要复习一下原来字节的知识,不然又被绕糊涂了。
;我们常说的二进制与十六进制,这个东西就是用于计算机使用的。
;一个字节是八位的,在二进制中,每位要么0,要么1.就是物理上的高电平与低电平,假设都是1,则一个字节的值是11111111,你可以数数,就有8个1了,这是一个字节能表达的最大值
;那一个字节能表达多少个值呢。你可以从00000000到11111111,挨个算
;00000000,00000001,00000011,00000111,00001111.....10000000,10000001......11111111
;8位的情况下,所有的组合,其实就是256个

;这样的表达很要命,后来找到一种更好的表达,就是十六进制
;它就是0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F,代表的是0到15,总共是16个
;它的组合就是0,1,2,3....9,A,B,C,D,E,F,10,11,....A0,A1,A2....AA,AB,AC...FD,FE,FF,总数也是256个
;你留意一下,十六进制的FF,就是二进制的11111111,就是十进制的255,也就是一个字节能表达的最大值

;回到代码上来,你会发现4294967296转换成十六进制是100000000,但是1个字节的最大值是FF,那eax是4个字节,那最大是FFFFFFFF,只能塞进8个F,而这个100000000有9个值,塞不进去了
;那这个时候就把低位的塞到eax里去,这里低位的就是8个0,所以mov eax,0
;把高位的,就是100000000里面的1,塞进edx里去,就有前面的edx,1

;要是乘法的结果,超出了这个值,怎么办呢。这个就是反过来,edx里放结果的高位值,eax里面放结果的低位值。
;这个涉及到标志位,又有新知识,下次专门讲一下操作了,先学简单的,慢慢地进步。

;当然,大部分的时候,用不上这么大的值,基本上用eax或ebx之类的就可以。
;仔细想想,我想你应该能明白了。

;当然,并不是只能用寄存器来进行计算,也可以用内存来计算,原理类似,只是表达的不同,下次专门讲一讲。
;关于如何用内存来计算,可以查看本博客有关的其它文章,也有详细的示例说明。

;以下是资源Rc文件内容
#include "resource.h"

#define    ICO_MAIN      1000    //图标

#define IDB01 101
#define IDB02 102
#define IDB03 103
#define IDB04 104
#define IDB05 105

ICO_MAIN    ICON        "Main.ico"

MyDialog DIALOGEX 10, 10, 110, 130 
STYLE  WS_SYSMENU|WS_CAPTION|WS_MINIMIZEBOX|WS_BORDER|DS_CENTER|DS_SETFONT|DS_3DLOOK 
CAPTION "我是对话框程序"
FONT 12, "方正姚体" 
BEGIN 
     PUSHBUTTON "计算 11+22 ",IDB01,10,20,90,12 
     PUSHBUTTON "计算 22-11 ",IDB02,10,40,90,12
     PUSHBUTTON "计算 11*22 ",IDB03,10,60,90,12
     PUSHBUTTON "计算 4294967295/11 ",IDB04,10,80,90,12
     PUSHBUTTON "计算 4294967296/11 ",IDB05,10,100,90,12
END 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一品人家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值