彙編總結-第二部分_1_數據傳送

這一篇主要說明數據傳送的問題。

 

首先,在AT&T彙編中的數據也是分類的。我記得學win16彙編的時候沒有這個概念,只知道可以按寄存器的高低位來傳送數據。下面是win32彙編的幾種命令:

 

.ascii

文本字符串(不帶’\0’)

.asciz

以空格符結尾的文本字符串

.byte

字節值

.double

雙精度浮點數

.float

單精度浮點數

.int

32位整數

.long

同上

.octa

16字節整數

.quad

8字節整數

.short

16位整數

.single

單精度浮點數(同float)

 

 

這裏有個小技巧,在數據段中可以定義一個.equ  名字 常量

那麼這個名字就成了這個常量的代替。有點像是C中的宏定義。

 

關於.bss段還有兩個配合使用的命令

.comm           聲明未初始化的數據的通用內存區域

.lcomm          聲明未初始化的數據的本地通用內存區域。

comm段聲明的區域屬於共享內存段中的。

但是lcomm是不會從本地彙編代碼之外進行數據訪問的。

還有上一節我提到的,bss段的數據是不包含在可執行文件中的。但是數據段(data)必須包含在可執行文件中。

 

 

在.data段中還可以使用一個命令可以分配空間並且自動填充0。

用法如下:

.section .data

Buffer:

 .fill 1000

表示創建一個buffer段,並且生成1000個字節的內存區域,並且自動填充爲0。

這個應該可以用來實現C標準庫函數中的memset函數。不用for循環,效率也高了。

不過只能對data用。

 

關於數據傳送的重點就是mov指令了

在AT&T彙編中,mov是分長度的。Windows彙編是不分長度的。。(話說AT&T彙編真是各種麻煩)

movl用於32位的長字值

movw用於16位

movb用於8位

 

變質內存模式,表達式格式: 

Base_address (offset_address,index,size)

其意義爲

Base_address+offset_address+index*size

 

movl $2,%edi

movl values(,&edi<4),%eax

表示把第3個4字節的變址值加載到eax寄存器中

 

注意如果在一個標籤前面加上了$,那麼表示取這個標籤的地址,而不是值。

這個有點像C語言&的形式,但是符號是$.

 

GUN彙編器不允許把值與寄存器相加,必須把值放在括號之外

Movl  %edx,4(%edi)

  

由於時間關係。所以接下來的總結會比較簡略。

 

數據交換指令

XCHG

在兩個寄存器之間或寄存器和內存位置之間交換值

BSWAP

反轉一個32位寄存器中的字節順序

XADD

交換兩個值並且把總和存儲在目標操作數中

CMPXCHG

把一個值和一個外部值進行比較,並且交換它和另一個值

CMPXCHG8B

比較兩個64位值並且交換他們

BSWAP貌似對於網絡編程改變字節序很有用。應該是用來優化上層代碼的,直接把功能內置到CPU指令中了.

 

堆棧指令

Push和pop。這兩個指令使用ESP這個寄存器。

並且AT&T彙編一直是將內存區域從高到低來使用的。

也就是說每次PUSH,ESP都是遞減的。

注意:

其實彙編中說的‘堆棧’其實就是單指’棧’。(因爲這個說法弄的我一直沒看懂爲什麼malloc爲什麼分配之後存儲的不是0,以後再說爲什麼)

 

關於優化內存訪問

我個人總結如下:
1.內存基址對準,和C中結構體的對準一致。

2.避免分撒的小數據傳輸,使用單一的大型數據傳輸

3.避免在堆棧中使用大的數據長度,好比多媒體擴展的數和FPU存放的數(就是浮點寄存器)

4.將長度一致的變量設置在程序的開頭定義,而將長度不一致的放在程序的結尾定義。

 

附:gas彙編器支持.alig命令,用來在特定邊界內對準定義的數據元素。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章