Enterprise Just Builder

Solution for Enterprise Software Architecture

assembly

X64 寄存器、栈帧和汇编

多年以来人们一直使用 X86 汇编编写性能关键代码。随着 32位 CPU 逐渐被 64 位处理器取代,底层汇编代码也随之发生变化。本文将简单介绍 X64 汇编一些相关知识。了解 X86 汇编虽然有助于了解这种过渡,不过不是必要前提。http://www.ejb.cc/wp-admin/profile.php

X64 泛指 Intel/AMD 的 32 位 X86 指令集架构 (ISA) 的 64 位扩展。AMD 率先推出了第一代 X64 指令集。即 X86-64,后来被命名为 AMD64。Intel 的实现称为 IA-32e ,后来又改为 EMT64。这两个版本大致相同,只在一些细微处略有不兼容。详细可以参考 《Intel® 64 and IA-32 Architectures Software Developer’s Manuals》 和 《AMD64 Architecture Tech Docs》。本文中将其统称为 X64 ,以区分 Intel 64 位安腾架构 IA-64。

本文将不涉及缓存、分支预测等等与硬件相关的内容,如果读者感兴趣,可以参考本文列出的一些参考文章。1

汇编常被用来编写程序性能关键部分,虽然大部分程序员还是宁可选择好的 C++ 编译器。掌握汇编对代码调试十分有用,有时候编译器会产生错误的汇编代码,通过调试器单步执行代码可以有助于了解错误的原因;代码优化有时也会产生错误。如果手边没有源代码,你还可以通过汇编/反汇编来了解或修正手边的程序;此外如果你想深入了解语言的内部机制,比如方法 A为什么比方法 B 速度快,这时候汇编就十分必要;最后,在诊断恶意代码时,汇编也不可或缺。

架构
要学习平台汇编,首先就得了解寄存器集。

>>> 阅读全文

 

, ,

用汇编来学习 PC 的实模式、保护模式和长模式

本文主要面向那些有兴趣了解 CPU 是如何工作的用户,这里我将解释一些汇编语言基础知识、实模式、保护的模式和长模式。在文章的后面我还提供了完整的汇编代码,你可以用来测试看看处理器是如何在实模式下工作,如何进入保护模式,如何进入 64 位模式,最后又是如何从所有模式退出返回到 DOS。1

准备
要阅读本文以及进行相应的测试,你可能需要准备:

  • 汇编知识。虽然读者不需要编写代码,不过如果你对寄存器、内存访问、基本命令等有些了解会很有帮助。
  • Flat 汇编器。一个能生成 Win32, X64 和 DOS 下的可执行文件的“现代”汇编器。
  • 干净的 DOS 环境,你可以使用freeDOS

你无需在物理机上安装使用 DOS,相反你可以使用 VMWare 或者 Bochs 这样的虚拟机。这里我推荐使用 Bochs,不仅因为它是免费的,而且它的调试器可以陷入任何程序产生的异常,并告诉你到底发生了什么。

过去 Borland 的 Turbo 汇编器 (TASM) 十分流行,不过随着 Borland 的谢幕,TASM 也寿终正寝。附件中的所有代码都是用 FASM 编写的,该汇编器可以生成 16位的 DOS 以及 32/64位的 Windows 下的可执行文件。

你还可以在 Visual Studio 中找到 ML.exe 和 ML64.exe,这是 MASM 的新版本。不过该汇编器只能产生对应架构的 PE 格式,不适合这里的使用场景。

>>> 阅读全文

 

, , , ,

在 Visual C++ 中使用嵌入汇编

文章评价:
如果你的应用对性能要求十分严苛,使用汇编语言来进行编程无疑是最佳选择。不过,编程技术发展到今天,代码动辄百万行,直接用汇编语言来进行编程,成本实在太高了。作为一种折中方案,你可以选择在部分代码里使用汇编语言 — Inline Assembly 以达到改善性能的目的。
 
所谓嵌入汇编 — Inline Assembly 也叫做内联汇编,即直接在 C/C++ 代码里加入汇编语言代码。同传统的汇编方式相比,我们可以完全避免那些烦琐的汇编和链接步骤,可以直接在汇编代码中使用 C 变量名和函数名 。这样一来汇编代码就能够很容易地 C 语言程序紧密而自然地结合在一起了。另外,由于是把汇编语句和 C 或者 C++ 语句混合在一起进行编程,我们还将可以实现许多原来光凭 C 或者 C++ 语句无法办到的事。GCC, Visual C++ 等都提供了各自的嵌入汇编的实现。在 Visual C++ 中使用嵌入汇编不需要额外的编译器和联接器,十分的方便。

在 VC++ 中,嵌入汇编主要用于如下场合:

  • 使用汇编语言写函数;
  • 实现那些对速度要求非常高的代码;
  • 设备驱动程序中用于直接访问硬件;
  • “Naked” 函数的 prolog 和 epilog。

所谓 Naked 的函数,VC++ 不帮着做栈处理,需要用户自己取输入参数、保护寄存器、甚至自己写 ret 等等,因此称为 “纯粹”的函数(asm 函数)。有关 Naked 函数可以参考: Rules and Limitations for Naked Functions

嵌入汇编代码的缺点也很明显:代码不易于移植,如果你的程序打算在不同类型的机器(比如 x86 和 ARM)上运行,应当尽量避免使用嵌入汇编。特别要注意,微软在 64 位 VC++ 上已经不再支持嵌入汇编。这时候你应该使用 MASM,因为 MASM 支持更方便的的宏指令和数据指示符。

嵌入汇编关键字
在 Visual C++ 中加入嵌入汇编是只需要使用 __asm 关键字,这点和 C++ 标准不同,VC 不支持 C++ 中的 asm 关键字,所以你需要使用 __asm(两个下划线)关键字来编写你的嵌入汇编代码。这个关键字有两种使用方法:

>>> 阅读全文

 

, , , ,