进入x64时代用汇编写程序的越来越少了, 经常去的几个汇编论坛也越来越没人气. 也是,现在很少事情非得找到一个用汇编来写的理由了. 所以慢慢也就没落了.实际上32位汇编和x64汇编个人感觉差别也不大.为什么就没人用了呢..
作为一个看<<Windows环境下32位汇编语言程序设计>>步入编程领域的人, 闲来无事, 就把该书的随书例子都重新翻译成x64的. 总共18章加3个附录. 为了表示向罗云斌致敬, 本文题目就叫<<Windows环境下64位汇编语言程序设计>>.
x32上罗牛用的是MASM32的开发包, MASM32是一个好东西, 里面已经收集起来了开发windows程序所需要的编译器和头文件, 也都经过了较为严格的测试,总之之前我用MASM32基本没有遇到什么问题.
x64上,目前还没有MASM32那样的牛人来给我们收集头文件, 编译器和其他东西, 一方面可能有一些版权方面的问题, 一方面可能现在x64也不火了.没人搞这方面的工作,所以导致x64上用汇编很麻烦..难倒了很多新人. 就我在将<<Windows环境下32位汇编语言程序设计>>中的例子从32位修改到64位的过程中, 体会最深的一点就是并不是因为32位和64位寄存器大小的区别, 也不是堆栈传递参数的区别, 更不是其他的什么. 而是对齐问题. 对齐问题大部分又是因为头文件没有定义清楚. 所以我在修改的过程中. 一边写代码, 一边还要去修改头文件定义.. 很酸爽. 注意, 如果你在用x64汇编写程序的过程中遇到问题, 首先就想一想是不是对齐问题.. 现在堆栈都要按照16BYTE对齐, 不能乱搞了. 还有很多结构体也要按照16BYTE对齐.
为了修改<<Windows环境下32位汇编语言程序设计>>到x64上面, 我从vs2010里面copy出来了cl link rc等程序. 然后汇编器没有用vs2010的. ml64支持不了什么高级语法, 汇编想要写较大型程序必须要要有良好的结构体, 堆栈框架支持. 所以汇编器用的是开源的UASM
UASM是从之前的 JWasm 修改过来的, 这个汇编器还是开源的, 兼容MASM的语法. 另外头文件也是从JWasm那边搞过来的, 不过我加入了一些自己的私货. 比如C语言的头文件, 比如UNICODE支持. MASM32的时代我就已经找到了UNICODE支持中文办法, 不过一直没有推广出去. 如果你有幸看到这篇文章. 并且以后也会准备用汇编来写程序.. 一定不要再用老掉牙的ANSI编码, 而是要采用UNICODE来写.. 如果你用了附件我上传的开发包, 那么可以这样定义和使用UNICODE. 一种是在.const节里面定义字符串. 还有一种就向C语言一样定义字符串..
MASM支持中文UNICODE字符串定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; uasm -c -win64 Test.asm
; rc Test.rc
; Link /subsystem:windows Test.obj Test.res
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
option casemap:none
option win64:2
UNICODE equ True
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include unicode.inc
includelib user32.lib
includelib kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.const
szCaption db '恭喜', 0
szText db '当您看到这个信息的时候,您已经可以编译Win64汇编程序了!', 0
UszText UString ('当您看到这个信息的时候,',10,13,"您已经可以编译Win64汇编程序了", 21h, 0)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
Jmain Proc
; ANSI编码调用方式
;invoke MessageBox, NULL, offset szText, offset szCaption, MB_OK
; UNICODE调用方式
invoke MessageBox, NULL, offset UszText, offset UString$( "恭喜" ), MB_OK
invoke ExitProcess, NULL
Jmain Endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end Jmain
中文的完美支持. 依靠的就是unicode.inc 如果你下载附件的开发包,里面就已经自带了. 作者是陈浪涛. 也是个汇编高手. 有兴趣可以看看. 显然MASM的M不是Microsoft而是 Macro.. 用MASM的宏可以实现很多完全突破想象的功能, 这里有一个哥们就用MASM实现了面向对象. 有兴趣可以了解下.
关于附件中的例子编译方法和罗牛书上是一样的, 只是他用的是masm32 SDK包, 现在换成了UASM. UASM64压缩包解压到一个目录下, 运行目录下的set_path.bat就可以到各个例子目录下运行nmake了. 另外把TAB设置成8个BYTE. 这样显示出来的代码格式才正常.
//===========================================================================
下面是我修改例子程序的时候, 遇到的一些问题. 不过都已经被解决了..
无法接受和发送WM_COPYDATA消息, 原因是对齐方面的问题. COPYDATASTRUCT结构体必须按照16BYTE对齐. 我已经修改了winuser.inc文件, 将COPYDATASTRUCT结构体设置成了16BYTE对齐
C:\JASM64\luoyunbin\Chapter04\SendMessage-1
这个例子在win7 x64上已经试验不出效果了, 应该是win7的gdi画窗口的方式换了,不过虽然没有效果,我还是修改成了x64的版本.
C:\JASM64\luoyunbin\Chapter07\DcCopy
无法打开通用对话框 已修复OPENFILENAME对齐必须是16BYTE的. 所以我修改了系统的commdlg.inc后面的人就不会遇到这个坑了.
C:\JASM64\luoyunbin\Chapter09\Richedit
C:\JASM64\luoyunbin\Chapter10\FormatText
设置结构体对齐
pushcontext alignment
option fieldalign:16
popcontext alignment
这些无法打开通用对话框的问题都是由于没有设置对齐引起的. 这个问题折腾了好久好久. 他们说现在用汇编和C差不多, 相信用C肯定不会遇到这种问题. 不禁又让我想起了以前用汇编写驱动的时候, DriverEntry写出来死活崩溃. 偶尔又不崩溃. 最好找了好久的问题才发现原来DriverEntry里面不能动ebx. 如果动了ebx就会出错, 想用的话就要push保存起来. 这些都是一路走来的坑...
工具栏有编译错误,解决
C:\JASM64\luoyunbin\Chapter09\Toolbar
工具栏有编译错误,已解决
C:\JASM64\luoyunbin\Chapter09\Wordpad
工具栏错误解决, 主要是因为CommCtrl.inc头文件定义的有问题, 看来WinInc208 jwasm的作者还是没有masm32作者那样做那么多的测试.只是s使用h2incx工具转换好了就不管了. 这个转换难免还是有不少问题的..
屌爆了, C:\JASM64\luoyunbin\Chapter10\FindFile 里面使用了COM接口也被我修改成了x64修改了不少的接口定义. 还修改了系统头文件的几个定义, 系统的ShlObj.INC里面关于SHBrowseForFolder等几个函数的名称粉碎方式定义错了..
这是只适用于32位的例子.关于内存申请方面测试的例子, 所以就不修改了
C:\JASM64\luoyunbin\Chapter10\Fragment
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!