nasm程序从32位到64位平台的移植(一)

NASM是一个为可移植性与模块化而设计的一个80x86的汇编器

在视频编解码中经常会用到nasm对一些耗时较大的模块进行优化,比如变化量化、反量化反变换、SAD、SATD等的计算;

在32位到64位平台移植过程中,除了寄存器发生变化,比如eax->rax、ebx->rbx等,最主要的变化是参数传递的变化,在32位平台上,nasm的参数传递是通过堆栈(stack),而64位平台前n个参数由寄存器传递,超过n个的其他参数由堆栈传递(在64位unix系统中n等于6;在64位windows系统中n等于4)。

下面内容摘录自nasm(版本2.11.02)手册的第11节,如果有需要进行平台移植的可以参考nasm手册了解nasm的基础语法,以及下面两个关于ABI的链接熟悉在64位平台上参数传递和返回值的相关规则。

11.3、 64位C程序的接口(unix)

在Unix平台上,64位ABI定义在下面文档中:

http://www.nasm.us/links/unix64abi

尽管是为AT&T汇编写的,但是概念同样适用于NASM汇编代码。

下面是简单的总结

前6个整型参数(从左面开始)按顺序通过rdi,rsi,rdx,rcx,r8和r9进行传递,其他的整型参数通过stack传递。这些寄存器,加上rax,r10和r11在函数调用后被销毁,所以在使用它们的时候不需要保存。

整型返回值通过rax和rdx返回。

浮点数使用SSE寄存器,long double除外。浮点数参数通过XMM0到XMM7传递,通过XMM0和XMM1返回。long double 通过堆栈传递,通过ST0和ST1返回。

所有SSE和x87寄存器在函数调用后被销毁。

在64位Unix平台上,long类型是64bit的。

整型和SSE寄存器参数是分开计算的,所以下面的例子中

void foo(long a, double b, int c)

a通过rdi传递,b在xmm0中,c在rsi中。

11.4、 64位C程序的接口(Win64)

Win64 ABI 在下面链接中定义:

http://www.nasm.us/links/win64abi

下面是简单的总结:

前4个整型参数按顺序通过rcx,rdx,r8,r9传递。其他的整型参数通过堆栈(stack)传递。这些寄存器,加上rax,r10,和r11在函数调用后被销毁,所以在函数中使用的时候不需要保存。

整型返回值只通过rax传递。

浮点数使用SSE寄存器,long double除外。浮点数参数通过XMM0到XMM3传递,只通过XMM0返回。

在Win64平台上,long的长度是32bits,long long或者_int64是64bits。

整型和SSE寄存器参数是一起计算的,所以下面例子的

void foo(long long a,double b, int c)

a通过rcx传递,b在XMM1中,c在r8d中。


下面是32位和64位平台上的通用寄存器

nasm程序从32位到64位平台的移植(一)_第1张图片


在64位编程里可以使用20个8位寄存器,和16个16位、32位及64位寄存器。



你可能感兴趣的:(平台移植)