20 Some Years Later…

Twenty some years later, let’s imagine…

Archive for the 'Programming' Category

ASM on linux

因为想学学linux的内核 所以最近就看了些linux下的汇编
点点心得 记录一下

与win32汇编的区别

1.双字的字符定义
在汇编语言中,字符长度一般被分为3种,字节(Byte),字(Word),双字(Double Word),对应的长度分别为1个字节(8bit),2个字节和4个字节(在linux下还有代表四个字节的东东,不懂win32平台下有不,老师没提到过).
拿mov指令来做例子
在win32平台里,mov指令是没有字节长度之分的,也就是说一个mov指令你既可以用来移动字节,也可以用来移动字和双字.对于内存操作数,需要用到x ptr指令来定义移动的内存块的长度.比如要将一个双字的内存内容给EAX寄存器,应该写成:

[1]    mov dword ptr source, eax

在linux中,mov指令应该写成movx,x表示移动字节的长度,如movb代表移动一个字节的内容.在这需要特别说明的是,尽管Intel的文档里使用d(double)来表示双字,在linux的汇编环境下统一使用l(long)来代表双字,所以移动一个双字的指令就写成movl而不是movd.上面举的例子就应该写成:

[2]    movl source, %eax

2.寄存器的表示及间址寻址
在win32中,寄存器的表示方法就只需写出寄存器的名称就行,如第一个例子中的eax.间址寻址的方法是在寄存器名称外加个中括号,代表寄存器所指的内存区域,并且可以使用+/-立即数的方法来移动指针,如:

[3]    mov eax, [ebx]-3

在linux下,表示寄存器需要在其名称之前加上%前缀,参见第二个例子.间址寻址的方法也与win32平台有所不同,不是用的中括号而是使用括号,并且不能与立即数直接相加减,加减方法是在括号前写上被加数(相减的时候写负数),如:

[4]    movl %eax, -3(%ebx)

3.格式的区别
对于数据段,堆栈段,代码段的定义方式也有所不同,但这是死板的东西,在这就不举例了

一些新的东西
了解了指令优化,对于奔4处理器的预读取指令,还有函数及其参数在内存和堆栈中的存储方式.

No comments