一、 學習過程從c
語言的角度提出一些問題,這些問題再從彙編的角度考慮,還真的很有意思。
(1) 我們用高階語言程式設計時,一般不可能不用到變數,但是一定要用到變數嗎?還有這些變數從彙編的角度是怎麼實現的呢?畢竟暫存器和記憶體空間是不可能儲存乙個變化的值的,要改變暫存器和記憶體空間的值,只有重新賦值。但是原來老師講過,變數的宣告是給變數名開闢乙個固定大小的記憶體空間,所以宣告變數時一定要給定變數型別。如果不用變數的話,可以給每次要用到的引數重新賦值,但這樣就不能用迴圈等結構,會造成**重複冗長。
(2) c語言規定程式一定要從
main
函式開始執行,彙編規定程式要從
end後面的標號(一般是
start
)開始執行,那麼這兩者有什麼聯絡呢?是
main
函式在編譯時會變成
start
**段嗎?如果彙編裡
end後面沒有標號,程式會從頂部從上到下開始執行,那麼如果
c語言裡面沒有
main
函式,程式會由上到下執行嗎?彙編裡的
start
標號可以用其他標號代替,
c語言裡可不可以用其他函式代替
main
函式呢?
(3) printf函式可以接受不定量的引數,開始我覺得這沒什麼,但後來想了一下。我們自己定義的函式只能接受固定數量的引數,
printf
函式的這個功能是怎麼實現的呢?看了下函式原型,又查了下資料,
printf
使用了一種比較少見的語法叫「可變長引數」。但是我看了下資料介紹的實現可變長引數的巨集
va_list
如下:「(1)首先在函式裡定義乙個va_list型別的變數,這個變數是指向引數的指標;(2)然後用va_start巨集初始化剛定義的va_list變數,這個巨集的第二個引數是第乙個可變引數的前乙個引數,是乙個固定的引數;(3)然後用va_arg返回可變的引數,va_arg的第二個引數是你要返回的引數的型別,如果函式有多個可變引數的,依次呼叫va_arg獲取各個引數;(4)最後用va_end巨集結束可變引數的獲取。」但是如果要自己寫乙個printf
()函式的話,我覺得對於我還是相當有難度的。
二、 解決的問題
(1) c語言程式一定要用到變數嗎?答:可以不用變數,但是用變數寫程式更加簡潔方便。
(2) c語言程式怎麼實現變數的功能的?答:宣告變數開闢記憶體空間再接受賦值。
(3) printf函式的接收引數數量不定的功能是怎麼實現的呢?答:使用可變長引數的語法。
三、 未解決的問題
(1) c語言編譯時函式是怎麼轉化函式**段位址的?
(2) 如果c
語言裡面沒有
main
函式,程式會由上到下執行嗎?
(3) c語言裡可不可以用其他函式代替
main
函式呢?
四、 學習感想
我們往往為自己一貫的思想和別人的看法所束縛,這樣其實是很可悲的,而且更可悲的是我們平時沒有想法也沒有動力去搞清楚這些東西。只是簡單的會用就覺得這東西也就那樣了。但是其實簡單的東西也不簡單。printf函式有那麼多人用,有多少注意到它與別的函式的不同呢?特別是在寫程式時,往往就是自己覺得最不可能出錯的地方錯了,結果把**翻來覆去看了多少遍也找不出
bug來。我們平時在學習時,一定要注意細節,在程式設計時,思維一定要縝密,這樣才能減少錯誤,增加自己的效率。
從C語言到彙編,從彙編到C語言
看雪一同志寫的文章,我覺得很基礎和有用,知識著眼於小處。積累才是王道!一 迴圈語句與發彙編後的機器語言 1 for迴圈 下面是一段c語言的 我們的目的是來看其反彙編的結果 int myfunction int a,int b return c 前面的反彙編暫時不理它,這裡從for的地方開始反彙編,結...
彙編 C語言的IF轉彙編
include int main else return 0 對應彙編 如下 00ae1a10 push ebp 棧提公升 00ae1a11 mov ebp,esp 00ae1a13 sub esp,0d8h 00ae1a19 push ebx 儲存現場 00ae1a1a push esi 00ae...
彙編 C語言的for轉彙編
for 變數初始化操作 判斷是否執行迴圈 變數增減操作 提公升堆疊 00f83c00 push ebp 00f83c01 mov ebp,esp 00f83c03 sub esp,0cch 儲存現場 00f83c09 push ebx 00f83c0a push esi 00f83c0b push ...