※ 引述《coldstar.bbs@bbs.cs.nctu.edu.tw (灑落的月光伴著)》之銘言:
> ※ 引述《leicheong.bbs@bbs.sayya.org (理昌)》之銘言:
> > 這關乎parameter passing的方式.
> > 我想你找一下關於parameter passing的書/網頁看一下會比較清楚, 關鍵是
> > 只要compiler按照該function declare的方式, 把合適的東西(值或variable
> > pointer)放到calling convension下指定的位置(例如Pascal calling
> > conversion下是逆次序PUSH到stack)就可以了.
> 我不是這個意思
> 對 compiler 來說,要把 printf("%d", b) 最佳化成 printf("10")
> 應該需要 compiler 進 printf 裡實地觀察一遍才知道的吧?
> 但是現在的 compiler 已經這麼聰明了?
我了解你接二連三重複問的疑惑點
不妨直接看看 ICC 的編譯輸出吧
總之你原本所想的並沒有錯
傳入 printf 的 "%d" 和 b 兩個參數
當然沒有被自動換成 "10" 一個參數
剛好我手邊有 ICC
直接把貼 asm 結果給你看看
應該就能完全解惑了
ps. 參數我加了 /Ox : "enable maximum optimizations"
-----test.c-----
#include <stdio.h>
int main(){
const int a=10;
int b=0;
b+=a;
printf("%d",b);
return 0;
}
----------------
E:\>icl /Ox /S test.c
Intel(R) C++ Compiler for 32-bit applications, Version 9.0
Build 20051130Z Package ID: W_CC_C_9.0.028
Copyright (C) 1985-2005 Intel Corporation. All rights reserved.
test.c
E:\>
之後得出的 test.asm 節錄重要部分如下:
_main PROC NEAR
$B1$1: ; Preds $B1$0
push ebp ;2.11
mov ebp, esp ;2.11
sub esp, 3 ;2.11
and esp, -8 ;2.11
add esp, 4 ;2.11
push 3 ;2.11
call ___intel_new_proc_init ;2.11
; LOE ebx esi edi
$B1$5: ; Preds $B1$1
push 10 ;5.2
push OFFSET FLAT: __STRING$0$0$0 ;5.2
call _printf ;6.2
仍然是推入兩個參數到堆疊啦~
只是 b 就直接換成 immediate value (10) 了
但並沒有發生 "%d",10 直接被整合成一個 "10" 的事情...
; LOE ebx esi edi
$B1$6: ; Preds $B1$5
add esp, 12 ;6.2
; LOE ebx esi edi
$B1$2: ; Preds $B1$6
xor eax, eax ;7.9
mov esp, ebp ;7.9
pop ebp ;7.9
ret ;7.9
ALIGN 4
; LOE
; mark_end;
_main ENDP
_TEXT ENDS
_DATA1 SEGMENT DWORD PUBLIC FLAT 'DATA'
ALIGN 004H
__STRING$0$0$0 DB 37
DB 100
DB 0
上面三個 byte 就是原本的 "%d" 而已..
_DATA1 ENDS
_DATA SEGMENT DWORD PUBLIC FLAT 'DATA'
_DATA ENDS
; -- End _main
--
@, ●秘密情人● (bbs.cse.ttu.edu.tw)
~\ ◆ Post From: 140.129.20.3 ◆