組合語言的push疑問

組合語言push 0 push 1 push 2..等等

push [數字] 是什麼意思呢?

而這些數字 要怎麼知道裡面有什麼東西呢?

怎麼呈現?

希望有舉例

4 個解答

評分
  • 是我
    Lv 5
    1 0 年前
    最佳解答

    基本上您先要有堆疊 (stack) 的觀念。

    2009-05-14 08:50:55 補充:

    『push [數字] 是什麼意思呢』

    以 C 語言為例, 這問題有點類似問道 :

    『x = 0x34; 是什麼意思呢』

    『s = "0123456789"; 是什麼意思呢』

    顯然地, x = 0x34 是將 0x34 存放在變數 x (實際上可能是暫存器或記憶體) 中; 而“push [數字]”是將 [數字] 存放在記憶體中, 如此而已; 只是該記憶體的資料結構是 stack 罷了。

    『而這些數字 要怎麼知道裡面有什麼東西呢』

    這問題又有點類似問 (承上) :

    『0x34 裡面有什麼東西』

    『0x0040A0A4 裡面有什麼東西』(假設 "0123456789" 字串存放於位址 0x0040A0A4)

    顯然地, 0x34 是單純的數字, 無所謂的『裡面有什麼東西』, 但程式上”x = 0x34“一定有其意義的; 0x0040A0A4 也是數字, 較特殊的是它代表一記憶體位址, 若要說『裡面有什麼東西』, 那就是記憶體位址 0x0040A0A4 中有字串 "0123456789"。

    用以下簡單的程式碼 (Example.c) 為例 :

    int main(int argc, char* argv[])

    {

    char *p;

    p = strchr("0123456789", 0x34);

    printf("%lX\n", (long)p);

    return 0;

    }

    既然您提到 ollydbg, 就以 ollydbg 說明; 反組譯 (以上程式) 編譯後的 Example.exe :

    (註 : 以下的 Assembly 碼與位址因您所使用的編譯器而異)

    004011D4 >/. 55 PUSH EBP

    004011D5 |. 8BEC MOV EBP,ESP

    004011D7 |. 6A 34 PUSH 34 ; /c = 34 ('4')

    004011D9 |. 68 A4A04000 PUSH Example.0040A0A4 ; |s = "0123456789"

    004011DE |. E8 85100000 CALL Example._strchr ; \___org_strchr

    004011E3 |. 83C4 08 ADD ESP,8

    004011E6 |. 50 PUSH EAX ; /<%lX>

    004011E7 |. 68 AFA04000 PUSH Example.0040A0AF ; |format = "%lX"

    004011EC |. E8 5F270000 CALL Example._printf ; \___org_printf

    004011F1 |. 83C4 08 ADD ESP,8

    004011F4 |. 33C0 XOR EAX,EAX

    004011F6 |. 5D POP EBP

    004011F7 \. C3 RETN

    執行至 004011DE 時, 觀察 stack 的內容 (ESP = 0012FF84, ollydbg 右下方視窗) :

    0012FF84 0040A0A4 |s = "0123456789"

    0012FF88 00000034 \c = 34 ('4')

    即是將 0x34, 0x0040A0A4 『數字壓入堆疊』─ 置入堆疊記憶體中;

    『而這些數字 要怎麼知道裡面有什麼東西呢』

    0x34 僅是單純的數字(令 strchr 找尋的字元), 就不提了; 而 0x0040A0A4 則可用 ollydbg 左下方 Hex dump 的功能看該位址的內容 :

    Address Hex dump ASCII

    -------------------------------------------

    0040A0A4 30 31 32 33 34 35 36 37 01234567

    0040A0AC 38 39 00 25 6C 58 0A 00 89.%lX..

    即可看到 0x0040A0A4 位址『裡面有什麼東西』。

    『push [數字] 是什麼意思呢』

    答案很單純, 只是將『數字壓入堆疊』, 以供程式稍後使用。如以上的例子 :

    PUSH 34 - 欲找尋的字元 (strchr 的第二參數)

    PUSH 0040A0A4 - 目的字串 (strchr 的第一參數)

    CALL _strchr - _strchr 函數取出堆疊中的數字作為參數處理

    2009-05-14 08:51:15 補充:

    若您是問『那個被 push 的 [數字] 是什麼意思呢』或『push [數字] 的背後涵義是什麼呢』

    答案很就沒那麼單純; 從上例您可知道 PUSH 的數字是給 strchr 當參數使用, 但很多的情形下, 您無法知道函式實際的名稱, 您可能看到的是 :

    PUSH 12

    PUSH 5566

    PUSH 00123456

    CALL Example.00401234

    2009-05-14 08:51:22 補充:

    這樣子的組合語言碼, 您可能認為 12, 5566, 00123456 皆是 Example.00401234 的參數; 答案可能是, 也可能不是; 其真正的意義要從程式的上下文與了解 Example.00401234 是做啥才會知道, 這就是所謂的逆向工程 (Reverse Engineering)。若您對此有興趣, 在網路上可取得相當多的資訊。

    2009-05-14 08:51:34 補充:

    『記得是設定變數』

    從以上的 x = ..., s = ... 例子看來, 似乎是設定變數, 其實不然;

    若您將

    p = strchr("0123456789", 0x34);

    改為

    i = 0x34;

    p = strchr("0123456789", i);

    以在下的編譯器編譯後, 反組譯的結果是 :

    PUSH 34

    改變為

    MOV EAX,34

    PUSH EAX

    2009-05-14 08:51:41 補充:

    看到了嗎, i = 0x34 的 Assembly 為 MOX EAX,34, 並非使用 PUSH。不過這也依編譯器之不同而有不同的結果, 或許您的編譯器使用的是 PUSH。

    總之, PUSH 的唯一用途是將一數值置入堆疊中, 但應用方式就不唯一了。

  • Lv 4
    1 0 年前

    有關這些問題, 在說明時可能要case by case, 版主可能要說明一下您在哪段地方(進入副程式 / 程式開始 or ... )看到這些PUSH, 還有使用的CPU/MCU及編譯程式為何

    例如compiler將C轉成組合語言時, 它會用到一堆PUSH; 另外在組合語言進入INT routine時也有一堆; 而個別assembler的語法可能也會有點差異, 如果說明清楚, 大家會比較有共識 ~

  • 1 0 年前

    嗯 可是將數字壓入堆疊是什麼意思?

    2009-05-12 10:06:54 補充:

    記得是設定變數 可是在程式上 將軟體載入ollydbg 看到很多push數字 似乎不太像設定變數 ?

  • ㄚ旺
    Lv 5
    1 0 年前

    push [16bit 立即值]

還有問題?馬上發問,尋求解答。