##
**4.4**在組合語言中使用c語言庫函式
上乙個程式使用linux系統呼叫顯示cpu廠商資訊。還有一種不使用系統呼叫的方法,那就是使用c語言庫函式。
接下來通過呼叫c庫函式的printf()函式,編寫乙個呼叫printf()函式的新cpuid.s。
*4.4.1*使用printf
c庫包含很多c程式通用的很多函式。比如exit()和printf()。新的cpuid.s中的linux系統呼叫將被c庫函式所替代。
clib_cpuid.s如下:
.section .data
output:
.asciz 「the cpu id 『%s』\n」
.section .bss
. lcomm buffer, 12
.section .text
.globl _start
_start:
movl $0 ,%eax
cpuid
movl $buffer, %edi
movl %ebx, (%edi)
movl %edx, 4(%edi)
movl %ecx, 8(%edi)
pushl $output
pushl $buffer
call printf
addl $8, %esp
pushl $0
call exit
編譯 & 連線:
$ as -o clib_cpuid.o clib_cpuid.s
$ ld -dynamic-linker /lib/l-linux.so.2 -o clib_cpuid -lc clib_cpuid.o
如果你是32bit系統,不出意外可以成功的執行的。
接下來解釋下。
printf()函式需要兩個引數,第乙個是輸出的字串,這裡字串是帶有顯示變數的字串。
而且printf函式要求以空字元結尾的字串。.asciz命令定義的字串末尾是空字元。
接下來在.bss段建立了乙個緩衝區,這個緩衝區將要包含cpuid的資訊。使用.lcomm命令將其宣告為12位元組的緩衝區。在將cpuid資訊傳遞到緩衝區的過程和原來的程式的過程是一樣的。
為了使用c庫函式printf,需要使用pushl將需要的引數入棧。
需要注意的是入棧順序和printf函式的參數列順序是相反的。即就是首先將緩衝區buffer入棧,隨後是output入棧。入棧完成之後,使用call指令呼叫printf函式。addl指令用於清空printf函式放入堆疊的指令。使用exit函式的技術和printf函式相同。
*4.4.2*連線c庫函式
簡單地說,在組合語言程式中呼叫c庫函式,必須把c庫檔案連線到程式目標**。如果c庫函式不可用,顯然要報錯。
當我們使用gcc時,自動幫我們連線到了動態鏈結庫。但是在這裡我們需要手動地將動態鏈結庫連線到程式目標**以便c函式可以操作。
gnu聯結器使用 -l 引數,在使用這個引數時不需要指定庫名稱,預設的庫是 :/lib/libx.so。但是還必須指定在執行時載入動態庫的程式。linux中這個程式是ld-linux.so.2,位於/lib下。為了指定這個程式,使用gnu聯結器引數:dynamic-linker。如下:
$ ld -dynamic-linker /lib/ld-linux-so.2 -o cpuid -lc cpuid.o
這個才可以保證程式征程執行。它使用ld-linux-so.2動態引導程式載入了libc.so庫。
$ gcc -o cpuid cpuid.s
同樣可以執行並且得到相同的結果。
————————第四章完結—————
C語言中 使用方式
域寬 轉換字元 乙個轉換說明以 開始,以轉換字元結尾,域寬部分是可選的,每個轉換說明對應於乙個輸出引數,改引數被轉化換成有轉換說明規定的資料格式後輸出。注 如果 後面是非轉換字元,多數編譯系統將它作為普通字元輸出。域寬說明字元 意義 減號 在指定區域按左對齊方式輸出 沒有減號時為右對齊 加號 輸出正...
在Go語言中使用JSON
將乙個物件編碼成json資料,接受乙個inte ce 物件,返回byte和error func marshal v inte ce byte,error marshal函式將會遞迴遍歷整個物件,依次按成員型別對這個物件進行編碼,型別轉換規則如下 bool型別轉換為json的boolean 整數,浮點...
在PHP語言中使用JSON
目前,json已經成為最流行的資料交換格式之一,各大 的api幾乎都支援它。我寫過一篇 資料型別和json格式 它的設計思想。今天,我想總結一下php語言對它的支援,這是開發網際網路應用程式 特別是編寫api 必須了解的知識。從5.2版本開始,php原生提供json encode 和json dec...