程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言入門篇-06

C語言入門篇-06

編輯:關於C語言

好了,我們來講一下棧這個東西。它是個什麼東西呢?我們前面已經講過了啊,你不會忘記了吧,是一塊內存呀。如果你忘了,我 - -!

講棧,要講一些匯編知識喽,匯編,大神們都要掌握的東西呀,我們這些小菜菜們多少也了解一點吧,熟話說的好,藝多不壓身嘛,如果你會木工、電工、鋼斤工、焊工,那麼你夏天應該不會去干焊工,其它三個 你可能還要考慮哪個給的錢多干哪個,這就是藝多不壓身呀,再來,趁年輕應該多學幾門手藝哦。

介紹幾個我們用的著的指令就行了,我們不會關心太多細節,我們只講它的功能即可

第一個 MOV A,B 就是將B的值 給A,簡單吧,So Easy!如MOV EAX,10 就是EAX = 0X10

第二個 SUB A,B 就是將A的值 減掉B,如SUB EAX,10,就是EAX=EAX-0X10

第三個 LEA A,B 就是將B的地址給A,如LEA EDI,val 就是把val的首地址給EDI

第四個 rep stos dword ptr [edi] ,這個復雜一點,就是將EAX裡面的值 ,循環寫入 EDI 指向的地址裡去,循環一次,ECX的值-1,ECX=0結束循環,EDI的值+4

第五個 PUSH A 就是先將ESP-4,然後將A寫入ESP指向的位置,這個過程叫壓棧或進棧

第六個 POP A 就是先將ESP指向的值寫入到A,然後將ESP的值+4,這個過程叫彈棧或出棧

第七個 CALL FUN 就是調用函數,在這個操作進行的時候,要先將EIP的值壓入堆棧

第八個 RET 就是返回指令,將棧中的數據彈到EIP中

好了,差不多已經夠了,那麼大家可能會有幾個不明白的地方,如EAX,ECX,ESP,EIP 是什麼意思,做什麼用的?它們是寄存器,可以假想成是CPU的內存,其實還有許多寄存器,我們用的就是那麼幾個,可以點調試窗口中的 Register按鈕來調出寄存器窗口 如圖

142854161.jpg

我們來做一些簡單介紹:EAX 主要是用來累加和用的,用於普通計算

EBX,ESI,EDI 保存函數環境用的,ESI,EDI還用於字符串指令,暫不介紹

ECX 主要用於循環計數用的

EDX 我也忘了是干什麼用的了,通用

EIP 這個重要,始終指向將要執行的指令,由系統自動處理

ESP 始終指向棧頂

EBP 基址指針寄存器 EFL 標志寄存器

好了,就先介紹這麼多,我以前對這些東西掌握的可是很到家的哦,,時間久了,忘了 - - !下面的其它的寄存器大家可以不用了解了,涉及到一些其它的指令集,如MMX呀,SSE什麼什麼的,下面還有 ST0 - ST7 是浮點運算用的寄存器,我們一般也不怎麼涉及。


講了那麼多,我們來講一下棧這個數據結構,棧是一塊內存,我們把它們看成是 4個4個連續的內存空間,也就是說,如果 我們的棧是1KB,那麼可以把它看成256個4B的整數空間,既然是內存塊,那麼就有高低地址之分,我們假設最高地址為 0X00131288,ESP 剛開始就指向這裡,那麼入棧是什麼意思,就是先將ESP-4,那麼ESP= 0X00131284,然後將要入棧的數據寫入到 0X00131284 85 86 87 這四個地址裡,再入棧就是再將ESP -4 = 0X00131280 ,然後將要入棧的數據寫入到 0X00131280 81 82 83這四個地址裡,明白了吧,就這樣,棧是從大地址向著小地址伸長的,如果出棧呢,如POP EAX,就是先將80 81 82 83 這四個地址裡的數據 寫入到 EAX裡,然後再把ESP+4 = 0X00131284,好了這就是棧啦。你需要把這段話多讀幾遍,自己隨便指定一個ESP的值 ,然後用幾個PUSH POP 指令做做實驗。

好了,那麼我們來看一下函數喽:代碼如下

#include <stdio.h>
void swap(int a,int b)
{
    int tem = a;
    a = b;
    b = tem;
}
int main()
{
    int a =1;
    int b =2;
    swap(a,b); 
    return 0;
}

代碼很簡單的,由於這段比較難於理解,或者不好用文字來表述,我打算用視頻來描述一下

下載地址如下:

本節視頻下載地址

好了,這講就到這裡了,希望對你有幫助!。。。。大家一定要動手練習,這個看懂以後,你就會明白為什麼我們的SWAP函數沒有把值交換掉,我們再把代碼稍微修改一下,看看是什麼效果

#include <stdio.h>
void swap(int *pa,int *pb)
{
    int tem = *pa;
    *pa = *pb;
    *pb = tem;
}
int main()
{
    int a =1;
    int b =2;
    swap(&a,&b);   
    return 0;
}

這段代碼需要大家自己研究,過程同我視頻裡的一樣,如果你能自己搞懂,你就真的懂了,如果你不懂,那麼你還要從01 到 06 再多看幾遍。。。。。 - -! 88



本文出自 “千千阙歌” 博客,請務必保留此出處http://qianqianquege.blog.51cto.com/8004200/1304824

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved