linux彙編 常見問題 (zz)

來源:互聯網
上載者:User
 http://firstdot.spaces.live.com/

1.gcc嵌入彙編
(1). 在gcc嵌入彙編中輸入輸出使用相同的寄存器?

static void * __memcpy(void * to, const void * from, size_t n)
{
 int d0,d1,d2;
 __asm__ __volatile__(
  "rep;movsl/n/t"
  "testb $2,%b4/n/t"
  "je 1f/n/t"
  "movsw/n"
  "1:/ttestb $1,%b4/n/t"
  "je 2f/n/t"
  "movsb/n"
  "2:"
  :"=&c" (d0), "=&D" (d1), "=&S" (d2)
  :"0" (n/4), "q" (n), "1" ((long) to), "2" ((long) from)
  :"memory");
 return (to);
}

運算元0,1,2和3,5,6使用相同的寄存器的理解:
a. 3,5,6在輸入過程中將值n/4,to和from的地址讀入ecx,edi,esi寄存器中;
b. 0,1,2在輸出過程中將ecx,edi,esi寄存器中的值存入d0,d1,d2記憶體變數中。
c. 注意在上面的語句中也有"&"限定符,但輸入和輸出仍使用相同的寄存器,如運算元0和3都使用寄存器ecx,這是因為"0"限定的結果,如果

把"0" (n/4)換成"c" (n/4),則因為"=&c"的限定而使得編譯時間報錯。

(2). 關於gcc嵌入式彙編中"&"限定符的作用?
"&"限定符用於輸出運算元,使其唯一的使用某寄存器

int bar,foo;
__asm__ __volatile__(
 "call func /n/t"
 "mov ebx,%1"
 :"=a" (foo)
 :"r" (bar));

在gcc編譯時間預設會讓bar也使用eax寄存器,如果把"=a"改為"=&a",那麼foo將唯一使用eax,而讓bar使用其它的寄存器。

(3). _start和main的關係?
main是gcc看到的程式進入點,而ld和as所看到的程式進入點其實是_start。libc庫中的_start會調用main函數。
a. 編譯帶_start的組譯工具時的步驟:as -o a.o a.s,ld -o a a.o; gcc -g -c a.s,ld -o a a.o。(使用gcc編譯可以增加調試選項-g,這

時不能直接用gcc -o a a.s編譯的原因是gcc會預設在程式中尋找main函數,並且會將libc中的_start加入進來。如果直接用gcc -o a a.s編譯

,則會報兩個錯誤"重複的_start"和"沒找到main")
b. 編譯帶main的組譯工具或C程式時的步驟:gcc -o a a.s;gcc -o a a.c。

(4).section和.previous
將這兩個.section和.previous中間的代碼彙編到各自訂的段中,然後跳回去,將這之後的的代碼彙編到上一個section中(一般是.text段),

也就是自訂段之前的段。.section和.previous必須配套使用。

2. AT&T彙編
(1).data,.section等都是偽操作,不能直接翻譯成機器碼,只有相應的assembler才能識別
(2).section將程式分成幾個片斷,如.data,.text,.bss
(3).globl 函數名表示該函數被export,並可以被其它檔案中的函數調用
(4).bss可以用來申請一塊空間,但不需要對其進行初始化
(5)使用核心定義函數如open,read等可以通過int $80中斷來完成
(6)MOVL $FOO,%EAX是把FOO在記憶體中的地址放到EAX中,而MOVL FOO,%EAX是把FOO這個變數的內容放入EAX
(7).include "檔案名稱",將其它檔案包含進來
(8)如何在彙編中表示結構?如c語言中的如下結構:
struct para
{
 char Firstname[40];
 char Lastname[40];
 char Address[240];
 long Age;//4 bytes
}
在彙編中可以表示成:
.section data
record1:
.ascii "Fredrick/0"
.rept 31 #Padding to 40 bytes
.byte 0
.endr
.ascii "Bartlett/0"
.rept 31 #Padding to 40 bytes
.byte 0
.endr
.ascii "4242 S Prairie/nTulsa, OK 55555/0"
.rept 209 #Padding to 240 bytes
.byte 0
.endr
.long 45
其中.rept n和.endr表示重複兩者之間的序列n次,可用於填充資料
(9)當組譯工具由多個檔案構成時,可以採用以下方式編譯與串連:
as write-records.s -o write-records.o (gcc -g -c write-records.s)
as write-record.s -o write-record.o (gcc -g -c write-record.s)
ld write-record.o write-records.o -o write-records
(10)如何在組合語言中使用動態庫中的函數?
#helloworld-lib.s
.section .data
helloworld:
.ascii "hello world/n/0"
.section .text
.globl _start
_start:
pushl $helloworld
call printf
pushl $0
call exit

as helloworld-lib.s -o helloworld-lib.o
ld -dynamic-linker /lib/ld-linux.so.2 -o helloworld-lib helloworld-lib.o -lc
產生動態庫:ld -shared write-record.o read-record.o -o librecord.so
(11)使用彙編檔案產生動態庫
as write-record.s -o write-record.o
as read-record.s -o read-record.o
ld -shared write-record.o read-record.o -o librecord.so
as write-records.s -o write-records.o
ld -L . -dynamic-linker /lib/ld-linux.so.2 -o write-records -lrecord write-records.o
記得運行write-records時還需要將動態庫路徑加到/etc/ld.so.conf中,並運行ldconfig
(12)編譯彙編檔案時如何產生偵錯符號
as --gstabs a.s -0 a.o 或者gcc -g -c a.s

附錄:
(1)函數調用時棧的情況
#Parameter #N <--- N*4+4(%ebp)
#...
#Parameter 2 <--- 12(%ebp)
#Parameter 1 <--- 8(%ebp)
#Return Address <--- 4(%ebp)
#Old %ebp <--- (%ebp)
#Local Variable 1 <--- -4(%ebp)
#Local Variable 2 <--- -8(%ebp) and (%esp)

(2)例子
 .include "external_func.s"

 .section .data
data_array:     #定義long型數組
 .long 3,67,34,0        
data_strings:    #定義字串
 .ascii "Hello there/0"
data_long: #定義long型變數
 .long 5

 .section .bss
 .lcomm my_buffer, 500   #申請一塊500位元組的記憶體

 .section .text
 .equ LINUX_SYSCALL, 0x80 #定義符號LINUX_SYSCALL的值為0x80
 .globl _start
_start:
 pushl %edx
 movl data_long,%edx     #將data_long變數的值放入edx寄存器
 movl $data_long,%edx    #將data_long的地址放入edx寄存器
 popl %edx

 pushl $3      #push second argument
 pushl $2      #push first argument
 call power    #call the function
 addl $8, %esp #move the stack pointer back
 pushl %eax    #save the first answer before,calling the next function

 movl $1, %eax #exit (%ebx is returned)
 int $LINUX_SYSCALL    

 .type power, @function #定義函數power
power:
 pushl %ebp         #save old base pointer
 movl %esp, %ebp    #make stack pointer the base pointer
 subl $4, %esp      #get room for our local storage
 movl 8(%ebp), %eax #put first argument in %eax
 movl 12(%ebp), %ebx #put second argument in %ebx
 imull %ebx,%eax
 movl %ebp, %esp    #restore the stack pointer
 popl %ebp          #restore the base pointer
 ret

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.