WindowsX64汇编入门(1)

WindowsX64汇编⼊门(1)
最近断断续续接触了些64位汇编的知识,这⾥⼩结⼀下,⼀是阶段学习的回顾,⼆是希望对64位汇编新⼿有所帮助。我也是刚接触这⽅⾯知识,⽂中肯定有错误之处,⼤家多指正。
中国热加工网⽂章的标题包含了本⽂的四⽅⾯主要内容:
(1)Windows:本⽂是在windows环境下的汇编程序设计,调试环境为Windows Vista 64位版,调⽤的均为windows API。
(2)X64:本⽂讨论的是x64汇编,这⾥的x64表⽰AMD64和Intel的EM64T,⽽不包括IA64。⾄于三者间的区别,可⾃⾏搜索。
(3)汇编:顾名思义,本⽂讨论的编程语⾔是汇编,其它⾼级语⾔的64位编程均不属于讨论范畴。
阴阳鱼(4)⼊门:既是⼊门,便不会很全。其⼀,⽂中有很多知识仅仅点到为⽌,更深⼊的学习留待⽇后努⼒。其⼆,便于类似我这样刚接触x64汇编的新⼿⼊门。
本⽂所有代码的调试环境:Windows Vista x64,Intel Core 2 Duo。
1.  建⽴开发环境1.1  编译器的选择对应于不同的x64汇编⼯具,开发环境也有所不同。最普遍的要算微软的MASM,在x64环境中,相应的编译器已经更名为,随Visual Studio 2005⼀起发布。因此,如果你是微软的
忠实fans,直接安装VS2005既可。运⾏时,只需打开相应的64位命令⾏窗⼝(图1),便可以⽤ml64进⾏编译了。第⼆个推荐的编译器是GoASM,共包含三个⽂件:GoASM编译器、GoLINK链接器和GoRC资源编译器,且⾃带了Include⽬录。它的最⼤好外是⼩,不⽤为了学习64位汇编安装⼏个G 的VS。因此,本⽂的代码就在GoASM下编译。第三个Yasm,因为不熟,所以不再赘述,感兴趣的朋友⾃⾏测试吧。不同的编译器,语法会有⼀定差别,这在下⾯再说。1.2  IDE的选择搜遍了Internet也没有到⽀持asm64的IDE,甚⾄连个Editor都没有。因此,最简单的⽅法是⾃⾏修改EditPlus的masm语法⽂件,这也是我采⽤的⽅法,⾄少可以得到语法⾼亮。当然,如果你懒得动⼿,那就⽤notepad吧。没有IDE,每次编译时都要⼿动输⼊不少参数和选项,做个批处理就⾏了。1.3  硬件与操作系统硬件要求就是64位的CPU。操作系统也必须是64位的,如果在64位的CPU上安装了32位的操作系统,就算编译成功也⽆法运⾏程序。2.  寄存器的改变汇编是直接与寄存器打交道的语⾔,因此硬件对语⾔影响很⼤。先来看看x64与x32相⽐在硬件上多了什么,变了什么(图2)。    X64多了8个通⽤寄存器:R8、R9、R10、R11、R12、R13、R14、R15,当然,它们都是64位的。另外还增加了8个128位XMM寄存器,不过通常⽤不着。    X32中原有的寄存器在X64中均为扩展为64位,且名称的第
⼀个字母从E改为R。不过我们还是可以在64位程序中调⽤32位的寄存器,如RAX(64位)、EAX(低32)、AX(低16位)、AL(低8位)、AH(8到15位),相应的有R8、R8D、R8W和R8B。不过不要在程序中使⽤如AH之类的寄存器,因为在AMD的CPU上这种⽤法会与某些指令产⽣冲突。3.  第⼀个x64汇编程序本节,我们开始编写⾃⼰的第⼀个x64汇编程序。在这之前,先讲⼀下calling convention的改变。3.1  API调⽤⽅式把Calling convention放在第⼀个讲,代表它的重要性。在32位汇编中,我们调⽤⼀个API时,采⽤的是stdcall,它有两个特点:⼀是所有参数⼊栈,通过椎栈传递;⼆是被调⽤的API负责栈指针(ESP)的恢复,我们在调⽤MessageBox后不⽤add esp,14h,因为MessageBox已经恢复过了。⽽在x64汇编中,两⽅⾯都发⽣了变化。⼀是前四个参数分析通过四个寄存器传递:RCX、RDX、R8、R9,如果还有更多的参数,才通过椎栈传递。⼆是调⽤者负责椎栈空间的分配与回收。下⾯给出⼀段代码,功能是显⽰⼀个简单的MessageBox,注意对RSP的操作:
代码:
;⽰例代码1.asm
;语法:GoASM
DATA SECTION
text    db 'Hello x64!', 0
caption  db 'My First x64 Application', 0
CODE SECTION
START:
sub rsp,28h
xor r9d,r9d
nfdmlea r8, caption
lea rdx, text
xor rcx,rcx
call MessageBoxA
add rsp,28h
北京导航
ret
?
???    这段代码是在GoASM中编译,指令部分GoASM与ML64差不多,关键是⼀些宏的定义有差别。⽐如masm中的.code,在这⾥就成了CODE SECTION。下⾯再说区别,先编译。GoASM中编译分两步:
侯雄飞
(1)编译:goasm /x64 1.asm
(2)链接:golink 1.obj user32.dll
如果⼀些正常,命令⾏中应显⽰图3的内容。
运⾏⼀下,我们的第⼀个64位windows程序就运⾏了。
GoASM还有⼀个特点是⽀持宏:ARG和INVOKE,使⽤这两个宏可以免除程序员⾃⼰对椎栈进⾏操作。不过初学吗,还是从基础掌握⽐较好。下⾯的⼀段代码相同的功能的MASM代码,注意看看区别。ML64⾄今仍不⽀持宏,所以每⼀步⼯作都要⾃⼰做。
代码:
注塑机螺杆的选择;⽰例代码2.asm
;语法:ML64
extrn MessageBoxA: proc
.data
text    db 'Hello x64!', 0
caption  db 'My First x64 Application', 0
.code
Main proc
sub rsp,28h
xor r9d,r9d
lea r8, caption
lea rdx, text
xor rcx,rcx
call MessageBoxA
add rsp,28h
ret
Main ENDP
end
????    编译这段代码的命令⾏是:ml64 2.asm /link /subsystem:windows /entry:Main user32.lib。如果正常,应该如图5显⽰那样。
很有意思吧,在64位系统下,我们仍然调⽤user32的API。可能是名称⽤习惯了,微软⾃⼰都懒得改了吧。
3.2  64位的椎栈代码中还有⼀处值得注意,那就是sub rsp,28h和add rsp,28h。28h这个数值是怎么来的呢?⾸先,x64中椎栈被扩展为64位;其次,我们在调⽤MessageBoxA时,要给四个参数外加⼀个返回地址留空间,因
此8(位)*5=40=28h。另外⼀些⼩问题要注意,AMD64不⽀持push 32bit寄存器的指令,最好的⽅法就是push和pop都⽤64位寄存器。EM64T如何?看了下Intel的开发⼿册,各个指令都分三种情况:纯32位、纯64位和32与
64位混合。下⾯是⼿册的⽚段:Opcode*      Instruction        64-
Bit Mode      Compat/Leg Mode      DescriptionFF /6        PUSH r/m16        Valid                Valid            Push r/m16.FF /6        PUSH r/m32        N.E.                  Valid            Push r/m32.FF /6        PUSH r/m64        Valid                  N.E.          Push r/m64. Default o bits.    没别的好⽅法,使⽤中多注意,尽量在64位程序中保⽤64位寄存器。 4.  ⼀些参考资料写完了第⼀个hello world,本⽂就此打住。本还想写⼀些内容,但掌握不深,留待下回吧。感觉有些资料不得不在第⼀篇⽂章中放
出来,因为它们是现有学习x64汇编的最好教材了,⽂中很多代码和知识点也来⾃于这些资料。(1)《Moving to Windows x64》,出⾃:/Files/vista_x64.htm(2)GoASM的帮助⽂档,⽬前最好的64位
汇编教程。出⾃:www.uk(3)《开始进⾏ 64 位 Windows 系统编程之前需要了解的所有信息》,出⾃:www.microsoft/china/MSDN/library/Windev/64bit/issuesx64.mspx(4)来⾃CodeGurus
的两篇⽂章
《Assembler & Win64》,degurus.be/codegurus/Programming/assembler&win64_en.htm《bout RIP relative addressing》degurus.be/codegurus/Programming/riprelativeaddressing_en.htm(5)AMD
开发⼿册(6)Intel开发⼿册,注意是新的《ntel® 64 and IA-32 Architectures software Developer's Manual》

本文发布于:2024-09-20 14:44:12,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/648657.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:汇编   代码   编译器   椎栈   寄存器
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议