用 NASM 编写代码(转自http://www.codingnow.com/text/nasm.htm)

用 NASM 编写代码

 


本文主要为有汇编基础, 而习惯了用 VC 的 inline ASM 写代码的朋友们而作.

为什么要使用 NASM?

使用 inline asm 固然方便, 但是却不利于代码的移植. 加上 VC 对新指令集(3D Now! ,XMM 等)的支持速度不够, 使用起来很不方便, 所以我们往往采用外部汇编. 如果你以前熟悉 MASM 或是 TASM, 也不必更换, 否则云风推荐 NASM. NASM 及其文档在 http://www.web-sites.co.uk/nasm 可以下载的到. 使用前最好通读一遍文档. 本文只会强调一些重点部分, 而补充一点遗漏, 而不会全盘复述. NASM 支持各种最新的指令集, 有相当强大的宏语言支持. 你将得到比 VC 的 inline asm 更为灵活的使用空间.

选一个好的编程环境

将 VC 当作 NASM 的编辑环境是完全可行的, 只需要在 Tools->Customize->Tools 下加入 NASM.exe 作为外部工具. 这里不详细介绍. 云风推荐 Editplus 这款小巧实用的编辑器. 你可以指定各种关键字的颜色, 云风自己制作的语法文件在这里, 写的还不完备, 很多 nasm 的宏语句尚未加入, 另外还加了一些自己制作的宏. 所以请各位读者酌情修改. 加入 Editplus 的方法是在 Tools-> Preferences->Files->Syntax 里增加一个语法文件. Editplus 支持 output 窗口信息捕获, 在 Tools->Preferences->Tools->User Tools 里增加 NASM.exe, 并选 capture output 就可以了. 当然如果你想制作单独的 win32/pe 文件, 而不是编译成 obj 供 VC link, 那么还需要一个 link 程序. 最好再配合 makefile 使用.

如何编译成可供 VC 连接的 obj

NASM 支持多种输出格式, 虽然 VC 号称是使用的 COFF 格式, 但实际上是有区别的. NASM 除了输出 COFF 格式外, 另外也支持 VC 的目标文件格式, 叫做 win32. 我在 Editplus 的 user tools 里设置的是

	-i I:/nasm/include/ -f win32 -o $(FileNameNoExt).obj $(FileName)

注: 这里的 -i 后是头文件的路径 将编译出来的 obj 加入 VC 的 project 里就可以了. 一般来说, 目标文件有三个段, 分别是 text/data/bss 段.

  • text 段放置代码, 是只读且可运行段
  • data 段放置静态数据, 这些数据会被放置入 exe 文件. 这个段是可读写, 但是不能运行的.
  • bss 段放置动态数据, 这些数据不被放入 exe 文件, 在exe文件被加载入内存后才分配的空间.

一个简单的程序框架是这样的:


[bits 32]

[section .text]
global _func
_func:
; 这里写func 函数的代码

[section .data]

[section .bss]

这里, 用 global 声明了一个可被 C 调用的函数 func (C 函数都有一个下划线前缀) _func: 是这个函数的入口. 在对应的 C 代码里想使用 func 这个函数, 还需要用 extern 声明 func 是外部函数. 如果在 C++ 里使用则还需要将函数说明成 C 调用方式, 方法是用 extern "C" { } 说明

参数的传入和处理

函数的参数处理和其调用方式有关, C 的缺省调用方式是 _cdel 调用方式, C++ 的非静态成员函数采用的是 _thiscall, 关于各种调用方式的处理堆栈的方法, 在 MSDN 里可以查的到. 写 inline asm 可能很少涉及这些, 但是这里却必须搞清楚.

用纯汇编写 win32 程序等

写 WIN32 下的 win32/pe EXE, 我建议使用 Borland 的 obj 格式, 这是因为导入 DLL 中的 API 比较方便. 但是需要注意一些要点:

  • NASM 缺省使用的segment 是 USE16 的, 而在 win32 下必须使用 USE32, 而且必须指定段的类型. 所以必须在源文件头写上这样几行:
    
    [section .text class=code use32]
    [section .data class=data use32]
    [section .bss class=bss use32]
    %define __SECT__
    
  • Borland 的 OBJ 文件里可以指定开始的标签(..start), 一般可以写成这样:
    
    [section .text]
    ..start
    WinMain:
    
    你的代码将从 WinMain 这里开始运行.
  • 和 C 不一样, 你的主代码没有什么参数传入, 所以你必须自己来得到必要的参数. 比如:
    
    push dword 0
    call GetModuleHandle	; 获得 hInstance
    

    获得 Instance 句柄(到 eax).
  • 退出程序也不能直接用 ret, 因为你的程序是一个进程, 而不是一个函数, 所以必须调用:
    
    push dword 0	; 退出码
    call ExitProcess
    
  • 上面的 GetModuleHandle 是 kernel32.dll 里的 API: GetModuleHandleA, 所以需要在汇编源代码中声明导出:
    	import GetModuleHandle kernel32.dll GetModuleHandleA
    	extern GetModuleHandle
    
    另外 ExitProcess 也是这样:
    
    	import ExitProcess kernel32.dll
    	extern ExitProcess
    
    

    import 的具体用法请参考 NASM 的文档.

善于使用 NASM 强大的宏指令

这本是一个应该很丰富的 Section, 但是时间有限, 只举一个简单的例子, 定义下面这样一个宏:


%imacro callapi 1-*
%define %%api %1
	%rotate -1

	%rep %0-1 
	%rotate -1 
		push dword %2 
	%endrep 

	call %%api
%endmacro

然后, 比如你需要调用 MessageBox, 就可以这样写
callapi MessageBox,[hWnd],lpText,lpCap,0

  • hWnd 是一个全局变量保存的窗口句柄, 当然也可以是 0
  • lpText 是文字的字符串指针
  • lpCap 是MessageBox 的标题字符串

另外我自己还做了许多诸如处理函数参数, 保护堆栈等等方便使用的宏, 这里就不一一列出来了. 希望我引个头, 能让更多的朋友喜欢上 NASM <script language=JavaScript src="../gbook.js"></script>


签写留言
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要在Linux中安装NASM汇编器,有几种方法可以选择。 方法1: 1. 打开终端并进入需要安装NASM的目录,比如cd ~/ffmpeg_sources。 2. 下载NASM的源代码,可以使用命令:curl -O -L http://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.bz2。 3. 解压下载的源代码文件,可以使用命令:tar xjvf nasm-2.14.02.tar.bz2。 4. 进入解压后的nasm目录,可以使用命令:cd nasm-2.14.02。 5. 运行autogen.sh脚本,可以使用命令:./autogen.sh。 6. 配置安装路径,可以使用命令:./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin"。 7. 编译和安装NASM,可以使用命令:make && make install。 方法2: 1. 安装Bochs环境,可以使用命令:sudo apt-get install build-essential xorg-dev libgtk2.0-dev。 2. 安装NASM,可以使用命令:sudo apt-get install nasm。 方法3: 1. 创建一个repo文件,可以使用命令:vim /etc/yum.repos.d/nasm.repo。 2. 在repo文件中添加以下文本: [NASM] name = Netwide Assembler baseURL = HTTP://www.nasm.us/pub/nasm/stable/linux/ enabled = 1 gpgcheck = 0 [NASM测试] name = Netwide Assembler(发布候选版本) baseURL = HTTP://www.nasm.us/pub/nasm/testing/linux/ enabled = 0 gpgcheck = 0 [NASM快照] name = Netwide汇编程序(每日快照构建) baseURL = HTTP://www.nasm.us/pub/nasm/snapshots/latest/linux/ enabled = 0 gpgcheck = 0 3. 保存并关闭文件。 4. 现在可以使用命令安装NASM:sudo yum install nasm。 以上是三种在Linux中安装NASM的方法,请根据你的需求选择其中一种方法来进行安装。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

flashboy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值