Windows X86 64位汇编语言入门
汇编语言入门教程
汇编语言入门教程汇编语言是一种低级机器语言的抽象表示形式,它将计算机底层的指令表示为可读的文本形式。
掌握汇编语言对于理解计算机硬件和编写高效的程序非常重要。
本教程将带您从零开始学习汇编语言的基础知识和编程技巧。
第一部分:介绍和准备工作1.1什么是汇编语言?1.2为什么要学习汇编语言?1.3汇编语言的基本特点和用途1.4开发环境的准备第二部分:汇编语言基础2.1数据表示和计算机内存2.2寄存器和指令2.3内存寻址方式2.4常用汇编指令2.5标志寄存器和条件分支指令第三部分:汇编语言编程技巧3.1数据的传递和处理3.2循环和分支结构3.3子程序的调用和返回3.4输入和输出操作3.5中断处理和异常控制第四部分:实例和应用4.1计算机硬件的控制4.2内存和外设的读写操作4.3实践项目和应用案例第五部分:调试和优化5.1调试汇编程序5.2性能优化和代码压缩技巧5.3代码的移植和扩展在学习汇编语言时,您需要了解计算机的基本结构和组成部分,包括中央处理器(CPU)、寄存器、内存等。
您还需要安装一款支持汇编语言的集成开发环境(IDE),并了解如何进行编译、调试和执行程序。
在学习汇编语言的基础知识时,您将学习如何表示和处理不同类型的数据,例如整数、浮点数和字符串。
您还将学习如何使用寄存器进行数据传输和计算,以及如何使用不同的寻址方式访问内存中的数据。
在学习汇编语言的编程技巧时,您将学习如何使用循环和分支结构进行条件判断和控制流程。
您还将学习如何编写子程序进行模块化的程序设计,并学习如何进行输入和输出操作以及异常处理。
通过实例和应用的学习,您将了解如何使用汇编语言实现一些常见的功能和操作。
例如,您将学习如何控制计算机硬件,如显示器、键盘和鼠标等。
您还将学习如何进行内存和外设的读写操作,以及如何处理中断和异常。
最后,您将学习如何调试和优化汇编程序,以确保程序的正确性和性能。
您将学习如何使用调试工具进行单步调试和变量跟踪,并学习如何进行代码的优化和压缩。
汇编语言基于x86处理器
汇编语言基于x86处理器汇编语言是一种低级编程语言,它直接操作计算机硬件进行指令级编程。
在x86架构下,汇编语言主要用于编写操作系统、驱动程序以及底层的系统软件。
以下是一些关于x86汇编语言的参考内容:1. x86处理器的架构和特点:x86处理器系列有很多型号和版本,比如Intel的Pentium和Core系列、AMD的Athlon和Ryzen系列等。
了解每种型号处理器的架构和特点对于编写高效的汇编程序非常重要。
2. 汇编语言的基本语法:汇编语言是一种低级语言,它使用汇编指令来直接操作计算机硬件。
了解汇编语言的基本语法,包括寄存器、指令和操作码等内容,是编写汇编程序的基础。
3. 寄存器和内存:在x86汇编语言中,寄存器是非常重要的概念。
了解常用的寄存器,如通用寄存器、段寄存器以及标志寄存器,以及寄存器的使用方法和操作规则,在编写汇编程序时能够更加灵活地使用寄存器。
4. 指令集和操作码:x86处理器支持的指令集非常丰富,包括算术和逻辑指令、数据传输指令、控制指令等。
了解常用的指令集和操作码,以及它们的使用方法和功能,是编写汇编程序的基础。
5. 汇编程序的编写和调试:了解如何编写和调试汇编程序,包括使用汇编器将汇编代码转换为机器码、使用调试器进行程序的调试和内存的查看等。
学习汇编程序的编写和调试技巧,能够更加高效地完成汇编程序的开发和调试任务。
6. 汇编程序的优化:汇编语言可以直接操作硬件,因此在一些对性能要求较高的场景,使用汇编语言编写程序可以实现更高效的代码。
了解汇编程序的编译器优化和硬件优化方法,可以提高汇编程序的执行效率。
7. 汇编语言应用案例:了解汇编语言在实际项目中的应用案例,包括操作系统、驱动程序、嵌入式系统等。
通过学习实际应用案例,能够更好地理解汇编语言在底层系统软件开发中的重要性。
总之,汇编语言是一种低级编程语言,基于x86处理器的汇编语言编程需要了解x86处理器的架构和特点,掌握汇编语言的基本语法、指令集和操作码,熟悉寄存器和内存的使用方法,以及编写和调试汇编程序的技巧。
简明x86汇编语言教程
第一章汇编语言简介先说一点和实际编程关系不太大的东西。
当然,如果你迫切的想看到更实质的内容,完全可以先跳过这一章。
那么,我想可能有一个问题对于初学汇编的人来说非常重要,那就是:汇编语言到底是什么?汇编语言是一种最接近计算机核心的编码语言。
不同于任何高级语言,汇编语言几乎可以完全和机器语言一一对应。
不错,我们可以用机器语言写程序,但现在除了没有汇编程序的那些电脑之外,直接用机器语言写超过1000条以上指令的人大概只能算作那些被我们成为“圣人”的牺牲者一类了。
毕竟,记忆一些短小的助记符、由机器去考虑那些琐碎的配位过程和检查错误,比记忆大量的随计算机而改变的十六进制代码、可能弄错而没有任何提示要强的多。
熟练的汇编语言编码员甚至可以直接从十六进制代码中读出汇编语言的大致意思。
当然,我们有更好的工具——汇编器和反汇编器。
简单地说,汇编语言就是机器语言的一种可以被人读懂的形式,只不过它更容易记忆。
至于宏汇编,则是包含了宏支持的汇编语言,这可以让你编程的时候更专注于程序本身,而不是忙于计算和重写代码。
汇编语言除了机器语言之外最接近计算机硬件的编程语言。
由于它如此的接近计算机硬件,因此,它可以最大限度地发挥计算机硬件的性能。
用汇编语言编写的程序的速度通常要比高级语言和C/C++快很多--几倍,几十倍,甚至成百上千倍。
当然,解释语言,如解释型LISP,没有采用JIT技术的Java虚机中运行的Java 等等,其程序速度更无法与汇编语言程序同日而语。
永远不要忽视汇编语言的高速。
实际的应用系统中,我们往往会用汇编彻底重写某些经常调用的部分以期获得更高的性能。
应用汇编也许不能提高你的程序的稳定性,但至少,如果你非常小心的话,它也不会降低稳定性;与此同时,它可以大大地提高程序的运行速度。
我强烈建议所有的软件产品在最后Release之前对整个代码进行Profile,并适当地用汇编取代部分高级语言代码。
至少,汇编语言的知识可以告诉你一些有用的东西,比如,你有多少个寄存器可以用。
Windows X64汇编入门(1)
Windows X64汇编入门(1)tankaiha最近断断续续接触了些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环境中,相应的编译器已经更名为ml64.exe,随Visual Studio 2005一起发布。
因此,如果你是微软的忠实fans,直接安装VS2005既可。
运行时,只需打开相应的64位命令行窗口(图1),便可以用ml64进行编译了。
1.jpg下载此附件需要消耗2Kx,下载中会自动扣除。
第二个推荐的编译器是GoASM,共包含三个文件:GoASM编译器、GoLINK链接器和GoRC资源编译器,且自带了Include目录。
它的最大好外是小,不用为了学习64位汇编安装几个G 的VS。
因此,本文的代码就在GoASM下编译。
第三个Yasm,因为不熟,所以不再赘述,感兴趣的朋友自行测试吧。
不同的编译器,语法会有一定差别,这在下面再说。
1.2 IDE的选择搜遍了Internet也没有找到支持asm64的IDE,甚至连个Editor都没有。
X64汇编
64位汇编语言简介现在已经是64位的时代了,x86-64(AMD64)平台将是下一代计算机的体系结构,我们开发操作系统的当然要对x86-64的汇编有所了解。
1.x86-64的寄存器x86-64较x86-32多了8个通用寄存器,而且,每个通用寄存器都是64位宽,它们是:rax,rbx,rcx,rdx,rsi,rdi,rsp,rbpr8,r9,r10,r11,r12,r13,r14,r15同时,x86-64全面支持x86-32和x86-16的通用寄存器:eax,ax,al,ah,ebx,bx,bl,bh,....而且,还对传统的edi,esi做了改进:edi ,32位di,16位dil ,8位,在传统的x86机器中,di是不可按照8位来访问的,但在x86-64下可以。
同样esi也可以按照8位来访问。
一个很特别的寄存器rip,相当于x86-32的eip.在x86-32是不可直接访问的,如mov eax,eip是错的,但在x86-64位下却可以,如mov,rax,qword ptr [rip+100]是对的。
而且,它除了是个程序计数器外,也是个“数据基地址”,有此可见,它现在是身兼两职!为什么在x86-64位下要用rip做访问数据的基地址呢?因为,在x86-64下,DS,ES,CS,SS都没有实际意义了,也就是说,它们不再参与地址计算,只是为了兼容x86-32。
FS,GS还是参与地址计算,它们两个和x86-32的意义相同。
8位:al,ah16位:ax32位:eax64位:rax 新增(r8-r15寄存器,低32位r8d-r15d,低16位r8w-r15w,低8位r8b-r15b)2.x86-64的汇编x86-64的汇编和x86-32的没有多大的区别。
添加了新寄存器和指令。
操作符标示:8位:b16位:w32位:l64位:q写64位汇编代码时,可以用8、16、32、64位寄存器,如:push rdisub rsp, 48 ;mov r10, rcx; Line 36mov rdi, rdxxor eax, eaxmov ecx, 512rep stosb; Line 43movsxd r8, DWORD PTR [r10+16]mov QWORD PTR [rsp+32], rdxmov r9, QWORD PTR [r10+648]mov rdx, QWORD PTR [r10+52]mov rcx, QWORD PTR [r10+44]call fs_read_disk; Line 47mov ecx, 1cmp eax, ecxcmovne ecx, eaxmov eax, ecx; Line 52add rsp, 48pop rdiret 0再如:$L1818:; Line 2398mov al, BYTE PTR [rdx+rbx] cmp al, 32jne SHORT $L1819mov BYTE PTR [rdx+rbx], 0 $L1819:add r8d, 1movsxd rdx, r8dxor eax, eaxmov rcx, r12mov rdi, rbxrepne scasbnot rcxsub rcx, 1cmp rdx, rcxjb SHORT $L1818但,有点值得注意,当操作传统的32位寄存器时,那么,整个64位寄存器都会受到影响,如:mov eax,0ah那么,rax也等于000000000000000ah再如:mov rcx,0aaaaaaaaaaaaaaaah(此时ecx等于0aaaaaaaah)mov ecx,0ddddddddh(此时,rcx等于00000000ddddddddh,高32位受到了影响).规则:Example 1: 64-bit Add:Before:RAX =0002_0001_8000_2201RBX =0002_0002_0123_3301ADD RBX,RAX ;48 is a REX prefix for size.Result:RBX = 0004_0003_8123_5502Example 2: 32-bit Add:Before:RAX = 0002_0001_8000_2201 RBX = 0002_0002_0123_3301ADD EBX,EAX ;32-bit addResult:RBX = 0000_0000_8123_5502 (32-bit result is zero extended)Example 3: 16-bit Add:Before:RAX = 0002_0001_8000_2201 RBX = 0002_0002_0123_3301ADD BX,AX ;66 is 16-bit size override Result:RBX = 0002_0002_0123_5502 (bits 63:16 are preserved)Example 4: 8-bit Add:Before:RAX = 0002_0001_8000_2201 RBX = 0002_0002_0123_3301ADD BL,AL ;8-bit addResult:RBX = 0002_0002_0123_3302 (bits 63:08 are preserved)3.总结当然,这里说的都是最基本的东西,是针对通用寄存器言的。
汇编语言的学习步骤
汇编语言的学习步骤汇编语言作为低级语言的一种,是计算机硬件与高级编程语言之间的桥梁。
学习汇编语言可以帮助我们更深入地理解计算机底层的工作原理,提升编程的效率与质量。
下面是学习汇编语言的步骤,希望对你有所帮助。
Step 1:了解计算机体系结构在学习汇编语言之前,了解计算机的体系结构是非常重要的。
学习者需要了解计算机的组成部分,包括处理器、内存、输入输出设备以及其他外围设备。
掌握各组件之间的工作原理和相互关系,可以帮助我们理解汇编语言的运行机制。
Step 2:选取适合的汇编语言在市场上有多种不同的汇编语言可供选择,如x86、ARM等。
选择合适的汇编语言要根据自己的需求和实际情况进行判断。
一般而言,x86是最常见和广泛使用的汇编语言之一。
Step 3:学习汇编语言基础知识汇编语言是一种与硬件直接交互的语言,因此学习者需要掌握一些基础的概念和知识。
首先,了解各种指令的含义和功能,如数据传输指令、算术和逻辑指令等。
其次,要学会使用寄存器进行数据的读写和计算。
最后,掌握常用的编程技巧和调试方法,如单步执行、断点调试等。
Step 4:阅读汇编语言文档和教程阅读和理解汇编语言文档和教程是学习的关键。
可以选择一些经典的教材或者网络资源,比如《汇编语言》一书,或者在线的教学视频、博客文章等。
通过系统地学习和实践,逐渐掌握汇编语言的基本原理和技能。
Step 5:练习编写简单的程序尽早动手实践是掌握汇编语言的关键。
选择一些简单的编程项目,如计算器、加密算法等,通过编写相应的汇编语言程序来提升自己的编程能力。
可以加入一些汇编语言编程的社区或者论坛,与其他学习者一起交流和分享经验。
Step 6:深入学习高级的汇编语言特性一旦掌握了汇编语言的基础知识,可以进一步学习一些高级的特性和技巧,如宏汇编、模块化编程等。
学习者可以深入研究相关的文献和资料,提升自己的编程水平。
Step 7:应用汇编语言进行优化汇编语言被广泛应用于性能敏感的领域,如游戏开发、图形处理等。
x64汇编基础知识
x64汇编基础知识x64汇编语⾔在win32asm上做了较⼤改进,如果只凭借之前win32asm的只是来试⽔x64asm,则会有很多意想不到的bug,总的来说x64asm更加⾃由,更加有趣。
1.对32位寄存器的写操作和运算操作,则会对相应的64位寄存器的⾼32位清零。
如在x64dbg上实验,mov eax, 1和add eax, 1会使rax的⾼32位清零;xor eax, eax是对eax的清零运算操作,所以xor rax, rax会被编译器优化为指令更短的xor eax, eax因为⼆者在x64汇编中的效果是⼀样的;但是mov ax,1和mov al, 1不会对rax的⾼32位进⾏清零的操作。
2.⽴即数的使⽤,优先使⽤32位扩展,64位的⽴即数使⽤较少。
push指令和对内存的写操作只⽀持4字节的⽴即数数据,⽐如push 0x12345678和mov qword ptr [rax], 0x12345678是合法的,但是如果要对长度长于4字节的⽴即数使⽤(⽐如0x2134567890),就需要分两步进⾏,借⽤寄存器进⾏操作,如需要将0x1234567890压栈,应当:mov rax,0x2134567890; push rax.3.x64汇编的⼀些其他的基础知识⽐较常⽤的通⽤寄存器:rax eax ax alrcx ecx cx clrdx edx dx dlrbx ebx bx blrsp esp sp splrbp ebp bp bplrsi esi si silrdi edi di dilr8 r8d r8w r8br9 r9d r9w r9br10 r10d r10w r10br11 r11d r11w r11br12 r12d r12w r12br13 r13d r13w r13br14 r14d r14w r14br15 r15d r15w r15b此外还有rip, xmm0~xmm15的多媒体⽤寄存器,rflags。
x86架构汇编指令
x86架构汇编指令x86架构汇编指令是一种底层的机器语言指令集,用于在x86架构的计算机上执行任务。
它包含了一系列指令,用于操作寄存器、内存和其他硬件设备,以及进行算术和逻辑运算等操作。
本文将介绍几个常用的x86架构汇编指令,包括MOV、ADD、SUB和JMP。
1. MOV指令:MOV指令用于将数据从一个位置复制到另一个位置。
它的语法如下:MOV destination, source其中destination可以是一个寄存器或内存地址,source可以是一个寄存器、内存地址或立即数。
例如,MOV AX, BX将BX寄存器的值复制到AX寄存器中。
2. ADD指令:ADD指令用于将两个数相加,并将结果存储在目标位置。
它的语法如下:ADD destination, source其中destination可以是一个寄存器或内存地址,source可以是一个寄存器、内存地址或立即数。
例如,ADD AX, BX将AX寄存器的值与BX寄存器的值相加,并将结果存储在AX寄存器中。
3. SUB指令:SUB指令用于将两个数相减,并将结果存储在目标位置。
它的语法如下:SUB destination, source其中destination可以是一个寄存器或内存地址,source可以是一个寄存器、内存地址或立即数。
例如,SUB AX, BX将AX寄存器的值减去BX寄存器的值,并将结果存储在AX寄存器中。
4. JMP指令:JMP指令用于无条件地跳转到指定的地址。
它的语法如下:JMP destination其中destination可以是一个标签或地址。
例如,JMP LOOP将跳转到LOOP标签所在的位置。
除了上述指令外,x86架构汇编还包括许多其他指令,如CMP、AND、OR、NOT、XOR等,用于进行比较、逻辑运算和位操作等。
这些指令可以组合使用,以实现复杂的功能。
x86架构汇编指令的编写需要遵循一定的规范和语法。
每条指令都由一个助记符和操作数组成,它们之间用逗号隔开。
汇编语言:x86汇编指令大全及其注意事项
汇编语⾔:x86汇编指令⼤全及其注意事项⽬录Part 1:instructionPart 22.1 (逻辑)运算、移位等常⽤指令2.1 (逻辑)运算、移位等常⽤指令2.2 循环移位指令2.3 数据串操作指令2.4 逻辑运算指令2.5 基于⼤⼩关系的跳转指令2.6 基于单标志位的转移指令Part 1:instruction积少成多,持续更新。
(这将会是⼀个极其漫长的过程)表格中各条指令的顺序根据笔者所认为的重要或常⽤程度进⾏排序,仅供参考。
Part 2本表格中所涉及的F是指状态寄存器,CF指进位标志位,其它以此类推。
2.1 (逻辑)运算、移位等常⽤指令这⼀部分记录汇编语⾔程序设计当中使⽤频率最⾼的⼀部分指令。
2.1 (逻辑)运算、移位等常⽤指令这⼀部分记录汇编语⾔程序设计当中使⽤频率最⾼的⼀部分指令。
指令作⽤注意事项⽰例mov dest,src传送指令1.dest和src不能同时为存储器操作数2.CS不能作为dest3.段寄存器之间不能互相传送4.⽴即数不能送⼊段寄存器mov ax,wordptr[bx+si+2]adddest,src加法指令dest,src不能同时为存储器操作数或段寄存器add ax,cx adcdest,src带进位加法指令dest=dest+src+CF,常⽤于多字节加法inc dest加⼀指令 1.此操作不影响CF的状态inc byte ptr[si]subdest,src减法指令1.dest,src的要求与add相同2.触发OF:异号相减且结果的符号为与被减数不同sub ax,cxsbbdest,src带进位减法常⽤于多字节减法dec dest减⼀指令不影响CF的状态,但其他⼏个标志位都会受到影响dec axmul dest⽆符号乘法指1.dest为字节数据,则与AL相乘,结果放⼊AX2.dest为字数据,与AX相乘结果低16位放⼊AX,⾼16位放⼊DX3.dest不能是⽴即数mul aximul dest有符号乘法细节与mul完全相同,对最⾼位的解释不同imul axdiv dest⽆符号除法1.dest为字节数据,⽤AX除以dest,商放在AL,余数放在AH2.dest为字数据,⽤低16位为AX,⾼16位为DX的双字数据除以dest,商放在AX,余数放在DXidiv dest带符号除法与⽆符号完全相同。
64位汇编语言简介
x86-64位汇编语言简介一、x86-64的寄存器x86-64较x86-32多了8个通用寄存器,而且,每个通用寄存器都是64位宽,它们是:rax,rbx,rcx,rdx,rsi,rdi,rsp,rbpr8,r9,r10,r11,r12,r13,r14,r15同时,x86-64全面支持x86-32和x86-16的通用寄存器:eax,ax,al,ah,ebx,bx,bl,bh,....而且,还对传统的edi,esi做了改进:edi ,32位di,16位dil ,8位,在传统的x86机器中,di是不可按照8位来访问的,但在x86-64下可以。
同样esi也可以按照8位来访问。
一个很特别的寄存器rip,相当于x86-32的eip.在x86-32是不可直接访问的,如mov eax,eip是错的,但在x86-64位下却可以,如mov,rax,qword ptr [rip+100]是对的。
而且,它除了是个程序计数器外,也是个“数据基地址”,有此可见,它现在是身兼两职!为什么在x86-64位下要用rip做访问数据的基地址呢?因为,在x86-64下,DS,ES,CS,SS都没有实际意义了,也就是说,它们不再参与地址计算,只是为了兼容x86-32。
FS,GS还是参与地址计算,它们两个和x86-32的意义相同。
二、x86-64的汇编x86-64的汇编和x86-32的没有多大的区别。
添加了新寄存器和指令。
写64位汇编代码时,可以用8、16、32、64位寄存器,如:push rdisub rsp, 48 ;mov r10, rcx; Line 36mov rdi, rdxxor eax, eaxmov ecx, 512rep stosb; Line 43movsxd r8, DWORD PTR [r10+16]mov QWORD PTR [rsp+32], rdxmov r9, QWORD PTR [r10+648]mov rdx, QWORD PTR [r10+52]mov rcx, QWORD PTR [r10+44]call fs_read_disk; Line 47mov ecx, 1cmp eax, ecxcmovne ecx, eaxmov eax, ecx; Line 52add rsp, 48pop rdiret 0再如:$L1818:; Line 2398mov al, BYTE PTR [rdx+rbx]cmp al, 32jne SHORT $L1819mov BYTE PTR [rdx+rbx], 0$L1819:add r8d, 1movsxd rdx, r8dxor eax, eaxmov rcx, r12mov rdi, rbxrepne scasbnot rcxsub rcx, 1cmp rdx, rcxjb SHORT $L1818但,有点值得注意,当操作传统的32位寄存器时,那么,整个64位寄存器都会受到影响,如:mov eax,0ah那么,rax也等于000000000000000ah再如:mov rcx,0aaaaaaaaaaaaaaaah(此时ecx等于0aaaaaaaah)mov ecx,0ddddddddh(此时,rcx等于00000000ddddddddh,高32位受到了影响).规则:Example 1: 64-bit Add:Before:RAX =0002_0001_8000_2201RBX =0002_0002_0123_3301ADD RBX,RAX ;48 is a REX prefix for size.Result:RBX = 0004_0003_8123_5502Example 2: 32-bit Add:Before:RAX = 0002_0001_8000_2201RBX = 0002_0002_0123_3301ADD EBX,EAX ;32-bit addResult:RBX = 0000_0000_8123_5502(32-bit result is zero extended)Example 3: 16-bit Add:Before:RAX = 0002_0001_8000_2201RBX = 0002_0002_0123_3301ADD BX,AX ;66 is 16-bit size overrideResult:RBX = 0002_0002_0123_5502(bits 63:16 are preserved)Example 4: 8-bit Add:Before:RAX = 0002_0001_8000_2201RBX = 0002_0002_0123_3301ADD BL,AL ;8-bit addResult:RBX = 0002_0002_0123_3302(bits 63:08 are preserved)三、指令集变化小结:当然,这里说的都是最基本的东西,是针对通用寄存器言的。
简明X86汇编语言教程
简明X86汇编语言教程在计算机科学领域中,汇编语言是一种低级语言,用于编写和控制计算机硬件操作的程序。
X86汇编语言是一种广泛应用于个人电脑和服务器系统的指令集体系结构。
本教程将简明地介绍X86汇编语言的基本概念、语法和指令集,以帮助初学者入门。
下面将按照教程的逻辑顺序,逐步介绍相关内容。
1. 汇编语言简介汇编语言是机器语言的简化形式,通过使用助记符,可以更便于人们理解和编写程序。
我们将会一起了解如何使用X86汇编语言进行编程,包括数据类型、寄存器的使用和基本指令的命令格式等。
2. 数据传送和运算在这一部分,我们将会学习如何在寄存器中存储和传送数据,以及如何进行基本的算术和逻辑运算。
我们还将介绍一些常用的指令,例如mov、add、sub等。
3. 程序控制结构我们将介绍如何使用条件语句(如if-else和循环语句),以及如何使用标志寄存器来判断程序的执行流程。
同时,我们还将学习如何调用和返回函数。
4. 存储器管理在这个部分,我们将了解如何在程序中使用存储器。
我们将学习如何声明和定义变量、数组和常量,以及如何使用栈来管理函数的调用和返回。
5. 输入和输出我们将会学习如何从键盘读取输入,以及如何将数据输出到屏幕上。
通过学习这些知识,我们可以编写更加实用的程序,与用户进行交互。
6. 异常处理在这一部分,我们将介绍如何处理程序中的异常和错误。
我们将学习如何使用中断来响应外部事件,并进行相应的处理。
我们还将了解如何调试程序,以及如何优化程序的性能。
通过学习本教程,您将掌握X86汇编语言的基本知识和技巧,能够编写简单的汇编程序并进行调试和优化。
希望这个教程对您学习和理解汇编语言有所帮助。
总结本教程简明地介绍了X86汇编语言的基本概念、语法和指令集。
通过系统地学习和实践,您将逐渐掌握汇编语言的编程技巧,并能够编写出高效、可靠的汇编程序。
汇编语言虽然相对较低级,但在某些场景下仍然非常重要,因此掌握汇编语言将为您成为一名更全面的程序员打下稳固的基础。
x86汇编 讲解
x86汇编讲解摘要:1.x86 汇编简介2.x86 汇编的基本语法3.x86 汇编的寄存器和内存4.x86 汇编的指令集5.x86 汇编的应用场景正文:【x86 汇编简介】x86 汇编是一种用于编写计算机程序的低级编程语言。
它是x86 架构处理器的指令集体系结构(ISA) 的助记符表示形式。
x86 汇编语言可以用于编写操作系统、驱动程序和嵌入式系统等底层应用程序。
由于其底层特性,x86 汇编语言能够直接访问计算机硬件,并实现高性能的计算。
【x86 汇编的基本语法】x86 汇编语言的基本语法包括以下几个部分:1.指令:x86 汇编指令是用于完成特定任务的命令。
每个指令都有一个操作码,它表示指令要执行的操作。
操作码后面通常跟有一些操作数,用于指定操作的对象。
2.寄存器:x86 汇编中的寄存器是一组高速存储单元,用于存储数据和地址。
常用的寄存器包括通用寄存器(EAX、EBX、ECX、EDX)、指针寄存器(ESP、EBP)和索引寄存器(ESI、EDI)等。
3.内存:x86 汇编中的内存是指计算机中的主存储器,用于存储程序和数据。
内存地址通常用基址(Base Address)加偏移量(Displacement)的方式表示。
4.常用指令:x86 汇编中有很多常用指令,包括数据传输指令(如MOV)、算术指令(如ADD、SUB)、逻辑指令(如AND、OR)、跳转指令(如JMP、JZ、JNZ)等。
【x86 汇编的寄存器和内存】x86 汇编中的寄存器和内存扮演着非常重要的角色。
它们可以存储程序中的数据和地址,并在程序运行过程中进行高速读写。
以下是一些常用的寄存器和内存操作指令:1.寄存器指令:MOV 寄存器,数值将数值移动到指定的寄存器中。
2.内存指令:MOV 内存地址,寄存器将寄存器的值移动到指定的内存地址。
3.加载/存储指令:LOAD/STORE 寄存器,内存地址在内存和寄存器之间传输数据。
【x86 汇编的指令集】x86 汇编指令集非常丰富,可以完成各种复杂的操作。
WindowsX8664位汇编语言入门
WindowsX8664位汇编语言入门Windows x86-64位汇编语言入门汇编语言是计算机硬件和操作系统之间的桥梁,它能够直接控制计算机的底层硬件。
对于计算机科学的学习者来说,了解汇编语言是非常重要的一步。
本文将介绍如何入门并学习Windows x86-64位汇编语言。
一、了解汇编语言的基本概念在开始学习汇编语言之前,我们需要先了解一些基本概念。
汇编语言是一种低级语言,它使用助记符来代替机器指令,这样更方便我们理解和编写程序。
汇编语言的基本单位是指令,每条指令对应着一条机器指令。
在x86-64架构中,指令长度可以是1到15个字节。
二、安装并配置开发环境要开始编写和执行汇编语言程序,我们首先需要安装一个好的开发环境。
在Windows操作系统上,常用的开发环境有MASM、NASM、TASM等。
这些开发工具可以帮助我们将汇编代码转换为可执行文件。
三、学习汇编语言的语法和指令集汇编语言与其他高级编程语言相比,语法更加简单和直接。
学习汇编语言的关键就是理解和掌握其语法和指令集。
在学习过程中,我们可以参考官方文档或者一些经典的教程,如《汇编语言程序设计》。
四、编写你的第一个汇编程序现在,我们可以尝试编写自己的第一个汇编程序。
我们可以从一个简单的程序开始,比如输出一个简单的“Hello, World!”。
下面是示例代码:section .datamsg db 'Hello, World!', 0section .textglobal _start_start:; 输出字符串mov eax, 4mov ebx, 1mov ecx, msgmov edx, 13int 0x80; 退出程序mov eax, 1xor ebx, ebxint 0x80这个程序使用Linux系统调用来输出字符串,并退出程序。
我们可以使用汇编器将其编译成可执行文件,然后在命令行中运行。
五、深入学习汇编语言的高级特性一旦掌握了汇编语言的基础知识,我们就可以进一步学习一些高级特性,如函数调用、内存管理、寄存器的使用等。
x86汇编 语法
x86汇编语法
x86汇编语言是一种低级语言,用于编写在x86架构上运行的程序的机器代码。
它使用助记符表示指令,这些助记符通常与对应的机器代码指令相对应。
以下是一些x86汇编语言的语法要点:
1. 指令格式:x86汇编语言中的指令通常由操作码和操作数组成。
操作码指定要执行的操作,而操作数指定要操作的数据或寄存器。
例如,MOV指令将一个值从一个位置移动到另一个位置,其格式为“MOV destination, source”。
2. 寄存器:x86架构包含多个寄存器,用于存储数据和地址。
在汇编语言中,可以使用寄存器名来引用寄存器中的值。
例如,EAX寄存器可以表示为“EAX”。
3. 立即数:立即数是直接包含在指令中的数字值。
例如,MOV AX, 1000H指令将1000H(十进制为4096)移动到AX寄存器中。
4. 内存操作数:当需要从内存中读取或写入数据时,可以在指令中使用内存操作数。
内存操作数由一个基址和一个变址量组成,它们可以是寄存器或立即数。
例如,MOV AX, [BX+SI]指令将BX和SI寄存器的值相加,并将结果作为基址,从该基址处读取一个字(16位)到AX寄存器中。
5. 标志寄存器:x86架构包含一个标志寄存器,用于存储各种状态标志。
这些标志用于指示算术操作的结果、零标志、符号标志等。
在汇编语言中,可以使
用条件码指令来测试标志寄存器的值。
以上是x86汇编语言的一些基本语法要点。
学习x86汇编语言需要熟悉指令集、寄存器、内存操作数、标志寄存器等概念,并能够编写简单的程序来执行基本操作。
Windows X86 64位汇编语言入门
Windows X86-64位汇编语言入门Windows X64汇编入门(1)最近断断续续接触了些64位汇编的知识,这里小结一下,一是阶段学习的回顾,二是希望对64位汇编新手有所帮助。
我也是刚接触这方面知识,文中肯定有错误之处,大家多指正。
文章的标题包含了本文的四方面主要内容:(1)Windows:本文是在windows环境下的汇编程序设计,调试环境为Windows Vista64位版,调用的均为windows API。
(2)X64:本文讨论的是x64汇编,这里的x64表示AMD64和Intel的EM64T,而不包括IA64。
至于三者间的区别,可自行搜索。
(3)汇编:顾名思义,本文讨论的编程语言是汇编,其它高级语言的64位编程均不属于讨论范畴。
(4)入门:既是入门,便不会很全。
其一,文中有很多知识仅仅点到为止,更深入的学习留待日后努力。
其二,便于类似我这样刚接触x64汇编的新手入门。
本文所有代码的调试环境:Windows Vista x64,Intel Core2Duo。
1.建立开发环境1.1编译器的选择对应于不同的x64汇编工具,开发环境也有所不同。
最普遍的要算微软的MASM,在x64环境中,相应的编译器已经更名为ml64.exe,随Visual Studio2005一起发布。
因此,如果你是微软的忠实fans,直接安装VS2005既可。
运行时,只需打开相应的64位命令行窗口(图1),便可以用ml64进行编译了。
第二个推荐的编译器是GoASM,共包含三个文件:GoASM编译器、GoLINK链接器和GoRC资源编译器,且自带了Include目录。
它的最大好外是小,不用为了学习64位汇编安装几个G的VS。
因此,本文的代码就在GoASM下编译。
第三个Yasm,因为不熟,所以不再赘述,感兴趣的朋友自行测试吧。
不同的编译器,语法会有一定差别,这在下面再说。
1.2IDE的选择搜遍了Internet也没有找到支持asm64的IDE,甚至连个Editor都没有。
15丨汇编语言学习(二):熟悉X86汇编代码
15|汇编语言学习(二):熟悉X86汇编代码《手把手带你写一门编程语言》你好,我是宫文学。
上一节课,在开始写汇编代码之前,我先带着你在 CPU 架构方面做了一些基础的铺垫工作。
我希望能让你有个正确的认知:其实汇编语言的语法等层面的知识是很容易掌握的。
但要真正学懂汇编语言,关键还是要深入了解 CPU 架构。
今天这一节课,我们会再进一步,特别针对 X86 汇编代码来近距离分析一下。
我会带你吃生成汇编代码的工作就会顺畅很多了!好了,我们开始第一步,通过实际的示例程序,看看 X86 的汇编代码是什么样子的。
学习编译器生成的汇编代码按我个人的经验来说,学习汇编最快的方法,就是让别的编译器生成汇编代码给我们看。
比如,你可以用 C 语言写出表达式计算、函数调用、条件分支等不同的逻辑,然后让 C 语言的编译器编译一下,就知道这些逻辑对应的汇编代码是什么样子了,而且你还可以分析每条代码的作用。
这样看多了、分析多了以后,你自然就会对汇编语言越来越熟悉,也敢自己上手写了。
我们还是采用上一节课那个用 C 语言写的示例函数 foo,我们让这个函数接受一个整型的参数,把它加上 10 以后返回:接着,再输入下面的 clang 或 gcc 命令:然后我们用一个文本编辑器打开 foo.s,你就会看到下面这些汇编代码:123int foo (int a){return a+10;}123clang -S foo.c -o foo.s或gcc -S foo.c -o foo.s123456789101112 .section __TEXT,__text,regular,pure_instructions.build_version macos, 11, 0 sdk_version 11, 3.globl _foo ## -- Begin function foo.p2align 4, 0x90_foo: ## @foo.cfi_startproc## %bb.0:pushq %rbp.cfi_def_cfa_offset 16.cfi_offset %rbp, -16movq %rsp, %rbp.cfi_def_cfa_register %rbp你第一次看到这样的代码的时候,可能会有点被吓着。
汇编语言入门教程
汇编语言入门教程在学习汇编语言之前,我们先了解一些基本概念。
汇编语言是一种低级语言,它与计算机硬件直接相关。
它使用特定的指令集来操作计算机的寄存器、存储器和其他设备。
汇编语言的编程者必须具备对计算机硬件的深入了解,包括CPU的结构和指令集,以及内存的组织和管理。
在编写汇编语言程序时,我们首先需要选择合适的汇编器来将程序转换成机器码。
汇编器是一种将汇编语言转换为机器码的工具。
常用的汇编器有MASM、NASM和GNU汇编器。
在选择汇编器之前,我们需要了解所用计算机的硬件架构和操作系统的要求。
下面我们来看一个简单的汇编语言程序示例:```assemblysection .datamessage db 'Hello, World!', 0section .textglobal _start_start:; 输出字符串mov eax, 4mov ebx, 1mov ecx, messagemov edx, 13int 0x80; 退出程序mov eax, 1xor ebx, ebxint 0x80```在上面的示例中,我们定义了一个字符串变量message,并在程序中输出了该字符串。
首先,我们将字符串的地址保存在ecx寄存器中,然后使用系统调用将字符串输出到标准输出。
接下来,我们使用了另一个系统调用来退出程序。
我们将1保存在eax寄存器中,表示退出程序的系统调用编号。
通过将ebx寄存器的值设置为0,我们告诉操作系统程序退出时不返回任何错误代码。
这只是一个简单的汇编语言程序示例,但它涵盖了汇编语言程序的基本结构和语法。
在接下来的教程中,我们将逐步学习如何编写更复杂的汇编语言程序,并介绍汇编语言的各种特性和技巧。
64位下的相对指令地址-X86指令格式(操作码列和指令列解释)
64位下的相对指令地址-X86指令格式(操作码列和指令列解释)寻找64位系统某符号特征码时发现他的MOV指令⽤的是相对地址,之前32位下从来没听说MOV还能⽤相对地址,故查阅了下Intel指令⼿册。
在MOV指令介绍下找到如下介绍:In 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to additionalregisters (R8-R15). Use of the REX.W prefix promotes operation to 64 bits. See the summary chart at thebeginning of this section for encoding data and limits.在64位下仍使⽤32位操作数,REX.R扩展寄存器,REX.W扩展指令。
REX前缀结构:关于RIP的介绍:2.2.1.6 RIP-Relative AddressingA new addressing form, RIP-relative (relative instruction-pointer) addressing, is implemented in 64-bit mode. Aneffective address is formed by adding displacement to the 64-bit RIP of the next instruction.In IA-32 architecture and compatibility mode, addressing relative to the instruction pointer is available only withcontrol-transfer instructions. In 64-bit mode, instructions that use ModR/M addressing can use RIP-relativeaddressing. Without RIP-relative addressing, all ModR/M modes address memory relative to zero.RIP-relative addressing allows specific ModR/M modes to address memory relative to the 64-bit RIP using a signed32-bit displacement. This provides an offset range of ±2GB from the RIP. Table 2-7 shows the ModR/M and SIBencodings for RIP-relative addressing. Redundant forms of 32-bit displacement-addressing exist in the currentModR/M and SIB encodings. There is one ModR/M encoding and there are several SIB encodings. RIP-relativeaddressing is encoded using a redundant form.In 64-bit mode, the ModR/M Disp32 (32-bit displacement) encoding is re-defined to be RIP+Disp32 rather thandisplacement-only. See Table 2-7.The ModR/M encoding for RIP-relative addressing does not depend on using a prefix. Specifically, the r/m bit fieldencoding of 101B (used to select RIP-relative addressing) is not affected by the REX prefix. For example, selectingR13 (REX.B = 1, r/m = 101B) with mod = 00B still results in RIP-relative addressing. The 4-bit r/m field of REX.Bcombined with ModR/M is not fully decoded. In order to address R13 with no displacement, software must encodeR13 + 0 using a 1-byte displacement of zero.RIP-relative addressing is enabled by 64-bit mode, not by a 64-bit address-size. The use of the address-size prefixdoes not disable RIP-relative addressing. The effect of the address-size prefix is to truncate and zero-extend thecomputed effective address to 32 bits.RIP是64位的新特性,在64位下,指令使⽤特定的Mod\rm来使⽤RIP,RIP的偏移是32位故寻址范围为上下2GB。
汇编语言x86汇编指令集大全
汇编语言x86汇编指令集大全汇编语言是计算机体系结构学科中的重要内容之一,它可以直接操作计算机硬件,实现对机器指令的精确控制。
而x86汇编则是汇编语言中最常用的一种,它广泛应用于各类个人电脑和服务器等计算设备中。
x86汇编指令集是汇编语言中的核心,掌握其基本指令对于开发高效的汇编程序至关重要。
本文将介绍x86汇编指令集的各个方面,包括数据传输指令、算术运算指令、逻辑运算指令、分支控制指令以及其他常用指令等内容,以帮助读者全面理解和掌握x86汇编语言。
一、数据传输指令数据传输指令是汇编语言中最基本的指令之一,用于实现数据在寄存器、内存和I/O端口之间的传递。
常见的数据传输指令包括MOV、XCHG、PUSH和POP等。
MOV指令用于将数据从一个位置传送到另一个位置,可以将数据从内存中传送到寄存器,也可以将数据从寄存器传送到内存。
例如,MOV AX, BX表示将寄存器BX中的数据传送到寄存器AX中。
XCHG指令用于交换两个操作数的值,例如,XCHG AX, BX表示交换寄存器AX和BX中的数据。
PUSH指令将数据推入堆栈,POP指令从堆栈中弹出数据。
这两个指令常用于函数调用和局部变量的保存与恢复。
二、算术运算指令算术运算指令用于执行各种数值计算操作,包括加法、减法、乘法、除法以及取模等。
常见的算术运算指令包括ADD、SUB、MUL、DIV和IMUL等。
ADD指令用于进行加法运算,可以将两个操作数相加,并将结果保存在目标操作数中。
例如,ADD AX, BX表示将寄存器BX中的值加到寄存器AX中。
SUB指令用于进行减法运算,可以将目标操作数减去源操作数,并将结果保存在目标操作数中。
MUL指令用于进行无符号数的乘法运算,可以将一个操作数与寄存器中的值相乘,并将结果保存在一对寄存器中。
DIV指令用于进行无符号数的除法运算,可以将寄存器中的值除以一个操作数,并将商保存在一个寄存器中,余数保存在另一个寄存器中。
IMUL指令用于进行有符号数的乘法运算,功能与MUL指令类似,但结果为有符号数。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Windows X86-64位汇编语言入门Windows X64汇编入门(1)最近断断续续接触了些64位汇编的知识,这里小结一下,一是阶段学习的回顾,二是希望对64位汇编新手有所帮助。
我也是刚接触这方面知识,文中肯定有错误之处,大家多指正。
文章的标题包含了本文的四方面主要内容:(1)Windows:本文是在windows环境下的汇编程序设计,调试环境为Windows Vista64位版,调用的均为windows API。
(2)X64:本文讨论的是x64汇编,这里的x64表示AMD64和Intel的EM64T,而不包括IA64。
至于三者间的区别,可自行搜索。
(3)汇编:顾名思义,本文讨论的编程语言是汇编,其它高级语言的64位编程均不属于讨论范畴。
(4)入门:既是入门,便不会很全。
其一,文中有很多知识仅仅点到为止,更深入的学习留待日后努力。
其二,便于类似我这样刚接触x64汇编的新手入门。
本文所有代码的调试环境:Windows Vista x64,Intel Core2Duo。
1.建立开发环境1.1编译器的选择对应于不同的x64汇编工具,开发环境也有所不同。
最普遍的要算微软的MASM,在x64环境中,相应的编译器已经更名为ml64.exe,随Visual Studio2005一起发布。
因此,如果你是微软的忠实fans,直接安装VS2005既可。
运行时,只需打开相应的64位命令行窗口(图1),便可以用ml64进行编译了。
第二个推荐的编译器是GoASM,共包含三个文件:GoASM编译器、GoLINK链接器和GoRC资源编译器,且自带了Include目录。
它的最大好外是小,不用为了学习64位汇编安装几个G的VS。
因此,本文的代码就在GoASM下编译。
第三个Yasm,因为不熟,所以不再赘述,感兴趣的朋友自行测试吧。
不同的编译器,语法会有一定差别,这在下面再说。
1.2IDE的选择搜遍了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.1API调用方式把Calling convention放在第一个讲,代表它的重要性。
在32位汇编中,我们调用一个API时,采用的是stdcall,它有两个特点:一是所有参数入栈,通过椎栈传递;二是被调用的API负责栈指针(ESP)的恢复,我们在调用MessageBox后不用add esp,14h,因为MessageBox已经恢复过了。
而在x64汇编中,两方面都发生了变化。
一是前四个参数分析通过四个寄存器传递:RCX、RDX、R8、R9,如果还有更多的参数,才通过椎栈传递。
二是调用者负责椎栈空间的分配与回收。
下面给出一段代码,功能是显示一个简单的MessageBox,注意对RSP的操作:代码:这段代码是在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;语法:ML64extrn MessageBoxA:proc.datatext db'Hello x64!',0caption db'My First x64Application',0.codeMain procsub rsp,28hxor r9d,r9dlea r8,captionlea rdx,textxor rcx,rcxcall MessageBoxAadd rsp,28hretMain ENDPend编译这段代码的命令行是:ml64 2.asm/link/subsystem:windows/entry:Main user32.lib。
如果正常,应该如图5显示那样。
很有意思吧,在64位系统下,我们仍然调用user32的API。
可能是名称用习惯了,微软自己都懒得改了吧。
3.264位的椎栈代码中还有一处值得注意,那就是sub rsp,28h和add rsp,28h。
28h这个数值是怎么来的呢?首先,x64中椎栈被扩展为64位;其次,我们在调用MessageBoxA时,要给四个参数外加一个返回地址留空间,因此8(位)*5=40=28h。
另外一些小问题要注意,AMD64不支持push32bit寄存器的指令,最好的方法就是push和pop都用64位寄存器。
EM64T如何?看了下Intel的开发手册,各个指令都分三种情况:纯32位、纯64位和32与64位混合。
下面是手册的片段:Opcode*Instruction64-Bit Mode Compat /Leg Mode DescriptionFF/6PUSH r/m16ValidValid Push r/m16.FF/6PUSH r/m32N.E.Valid Push r/m32.FF/6PUSH r/m64ValidN.E.Push r/m64.Default operand size64-bits.没别的好方法,使用中多注意,尽量在64位程序中保用64位寄存器。
4.一些参考资料写完了第一个hello world,本文就此打住。
本还想写一些内容,但掌握不深,留待下回吧。
感觉有些资料不得不在第一篇文章中放出来,因为它们是现有学习x64汇编的最好教材了,文中很多代码和知识点也来自于这些资料。
(1)《Moving to Windows x64》,出自:/Files/vista_x64.htm (2)GoASM的帮助文档,目前最好的64位汇编教程。
出自:(3)《开始进行64位Windows系统编程之前需要了解的所有信息》,出自:/china/MSDN/library/Windev/64bit/issues x64.mspx(4)来自CodeGurus的两篇文章《Assembler&Win64》,http://www.codegurus.be/codegurus/Programming/assembler&win64_en.htm《bout RIP relative addressing》http://www.codegurus.be/codegurus/Programming/riprelativeaddressing_en.htm(5)AMD开发手册(6)Intel开发手册,注意是新的《ntel®64and IA-32Architectures software Developer’s Manual》Windows X64汇编入门(2)五一长假就要结束了,总算有时间好好睡了几个懒觉。
今天醒来后想到的第一件事就是,该写第二篇了。
64位技术现在还不成熟,没有好调试器,但是我们搞技术的总是对新东西充满了好奇和热情。
这个理由就足够我们现在开始学习64位汇编了!OK,Let’s go on。
1.再说Calling convention关于API的调用方式,在入门(1)中说了一些,不过感觉有必要再讲两点。
一是在调用API时椎栈的框架,也就是Stack Frame,二是利用反汇编64位C/C++程序来研究calling convention。
先说Stack Frame。
图1是一个通用的椎栈框架。
在一个使用STDCALL的32位程序中,stack frame的四项工作:(1)传入参数的调用;(2)在返回caller时,callee要负责平衡椎栈;(3)给局部变量提供空间;(4)保证ebx、esi、edi和ebp四个寄存器的值不变(这种寄存器被称为non-volatile)。
在64位环境中,少了一个平衡椎栈的任务,因为平衡椎栈的工作由caller负责了,因此callee的stack frame只剩下三项工作:(1)将寄存器传入的参数和其它超过4个以上的参数在椎栈上保存(入栈);(2)给局部变量提供空间;(3)保证non-volatile寄存器的值不变,包括ebp、ebx、rdi、rsi、r12到r15,xmm6到xmm15。
所以,在一个函数的开始往往有如下代码:MOV[RSP+8h],RCXMOV[RSP+10h],RDXMOV[RSP+18h],R8MOV[RSP+20h],R9PUSH RBPMOV RBP,RSP而在返回时会有如下代码:LEA RSP,[RBP]POP RBPRET图2摘自GoASM的帮助文档,上文描述的情况在图中一目了然。
如果能在VC中编译64位C/C++程序,再用IDA反汇编,不是挺好的吗?正确,这正是我们玩儿逆向工程的人喜欢的方法。
Visual Studio2005的64位开发环境设置网上有,这里不多说了。
以一个C/C++的代码为例:代码:ida64看一下它的反汇编。
这样,熟悉而又有点陌生的64位汇编代码就出来了,包括消息的判断,EndDialog的调用等,确实很方便。