汇编语言学习(一) |
您所在的位置:网站首页 › 数制转化器 › 汇编语言学习(一) |
汇编课程设计—数制转换器 刚学汇编语言,做了一个简单的数制转换器,由于二进制、十进制和十六进制之间的转换比较简单,所以我们主要做了二进制与十进制之间的转换,八进制与十进制之间的转换以及十六进制与十进制之间的转换。整个程序思想比较简单,但是完整的做下来不仅巩固所学、学以致用,而且对汇编语言的Windows编程也有了一个更深的理解。 首先,程序的主体就是显示一个最简洁的(连标题栏都不带的)窗口,这个跟C++的MFC编程一样,分为7步: 一、得到应用程序的句柄; invoke GetModuleHandle,NULL mov hInstance, eax 二、得到命令行参数; invoke GetCommandLine mov CommandLine, eax 三、注册窗口类 invoke RegisterClassEx, ADDR wc,当然之前要对窗口的基本属性进行定义,由于一般的窗口定义都大同小异,这部分代码就比较容易。 四、创建窗口对象 invoke CreateWindowEx, WS_EX_CLIENTEDGE, ADDR szClassName, ADDR szDisplayName, WS_POPUP or WS_CAPTION, Wtx,Wty,Wwd,Wht, NULL,NULL, hInst,NULL mov hWnd,eax 五、显示窗口 invoke ShowWindow,hWnd,SW_SHOWNORMAL 六、刷新窗口 invoke UpdateWindow,hWnd 七、消息循环 StartLoop: invoke GetMessage,ADDR msg,NULL,0,0 cmp eax, 0 je ExitLoop invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg jmp StartLoop ExitLoop: return msg.wParam 然后,是创建控件。从界面可以看到有3个静态文本框,2个编辑框,六个单选按钮,一个普通按钮。 一、 静态文本框的创建 Static proc lpText:DWORD,hParent:DWORD, a:DWORD,b:DWORD,wd:DWORD,ht:DWORD,ID:DWORD LOCAL hndle:DWORD szText statClass,"STATIC" invoke CreateWindowEx,WS_EX_DLGMODALFRAME, ADDR statClass,lpText, WS_CHILD or WS_VISIBLE or SS_LEFT, a,b,wd,ht,hParent,ID, hInstance,NULL mov hndle, eax invoke SendMessage,hndle,WM_SETFONT,hFont, 0 mov eax, hndle ret Static endp 主要是CreateWindowEx,参数参看MSDN就可以了。 二、编辑框的创建 EditSl proc szMsg:DWORD,a:DWORD,b:DWORD, wd:DWORD,ht:DWORD,hParent:DWORD,ID:DWORD LOCAL hndle:DWORD szText slEdit,"EDIT" invoke CreateWindowEx, WS_EX_CONTROLPARENT,ADDR slEdit,szMsg, WS_VISIBLE or WS_CHILDWINDOW or \ ES_AUTOHSCROLL or ES_NOHIDESEL, a,b,wd,ht,hParent,ID,hInstance,NULL mov hndle, eax invoke SendMessage,hndle,WM_SETFONT,hFont,1 mov eax, hndle ret EditSl endp 三、普通按钮的创建 PushButton proc lpText:DWORD,hParent:DWORD, a:DWORD,b:DWORD,wd:DWORD,ht:DWORD,ID:DWORD LOCAL hndle:DWORD szText btnClass,"BUTTON" invoke CreateWindowEx,0, ADDR btnClass,lpText, WS_CHILD or WS_VISIBLE, a,b,wd,ht,hParent,ID, hInstance,NULL mov hndle, eax invoke SendMessage,hndle,WM_SETFONT,hFont, 0 mov eax, hndle ret PushButton endp 四、单选按钮的创建 INVOKE CreateWindowEx, WS_EX_DLGMODALFRAME, CTXT("button"), addr szChange01,\ WS_CHILD or WS_VISIBLE or WS_TABSTOP or BS_AUTORADIOBUTTON,\ 00,90,200,30, hWnd, RadioID01, hInst, NULL mov hRadio01, eax 由于这个控件不常用,就没有单独为它写子程序了。 关于创建控件,在罗云斌那本书里讲的很详细,一般的书上也都有,看一下就明白了,这些东西基本上都这样,无非是对定义控件的风格的的参数可以改一下,基本上就没什么自由发挥的空间了,不过对于这些控件在窗口的位置倒是可以好好摆一下,排得好看一点,这个就是填写坐标参数之前先把坐标,高度很宽度计算一下,排得整齐一点。 最后就是对按键的处理,也就是消息响应的部分,具体在WndProc proc中是对WM_COMMAND的响应。 以十进制到二进制为例: 十进制到二进制将转换过程放在DecToOct proc过程中: DecToOct proc local @szBuffer1[256]:BYTE local @szBuffer2[256]:BYTE invoke GetDlgItemInt,hWnd,EditID01,NULL,FALSE .if eax mov ebx,8 lea esi,@szBuffer1 xor ecx,ecx .while eax!=0 xor edx,edx div ebx add edx,'0' mov [esi],edx inc esi inc ecx .endw ;除8取余 lea edi,@szBuffer2 .repeat mov edx, [esi-1] mov [edi],edx ;把存在@szBuffer1中的余数反过来存在@szBuffer2 中 inc edi dec esi .untilcxz mov BYTE ptr [edi],0 invoke SetDlgItemText, hWnd ,EditID02,addr @szBuffer2 .else invoke SetDlgItemInt, hWnd ,EditID02,eax,TRUE .endif ret DecToOct endp 采用的方法是将输入编辑框1中的数用GetDlgItemInt获取,返回值在eax中,不断地除二取余,将余数存在@szBuffer1中,然后再把余数倒过来存在@szBuffer2中,再由SetDlgItemText输出在编辑框2中,这里对eax里的值为0和不为0用分支处理,如果为0,则直接由SetDlgItemInt输出eax里的值。 二进制到十进制的转换过程放在OctToDec proc过程中: OctToDec proc local @szBuffer [512]:byte invoke GetDlgItemText, hWnd ,EditID01,addr @szBuffer,sizeof @szBuffer lea esi,@szBuffer cld xor eax,eax mov ebx,8 .while TRUE movzx ecx,BYTE ptr [esi] inc esi .break .if !ecx .if (ecx>='0')&&(ecx='a')&&(ecx='A')&&(ecx='0')&&(ecx='a')&&(ecx='A')&&(ecx='0')&&(ecx= dwLen ;若当前位置大于长度则重新开始 xor eax,eax mov dwNum,eax .endif invoke SetWindowText,hWin,offset szBuf 这里采用两个变量dwLen来存标题长度的字节数 ,dwNum 存放走过的长度的字节数,其实就是通过时间控制每次从当前位置一个字节一个字节往后移的来显示,要特别注意的是如果显示的字符串里既有汉字又有其他非汉字的字符就比较麻烦了,因为汉字占两个字节,其他的字符占一个字节,这样不管每次下移一个字节还是两个字节都会存在对不齐的问题,也就可能在标题栏里显示乱码。一个解决方法是采用UNICODE来存要显示的字符串,因为UNICODE都是两个字节,不存在对齐问题,不过比较麻烦而已,而且对应的函数还要换。我的这个程序为了避免这个麻烦就只使用了英文字符,也不用转换编码了。 完整代码将在下一篇里贴出来。 |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |