# 使用 LLVM IR 語言,打印出一個帶有參數的字串 完整的code: ``` ; ModuleID = 'example' source_filename = "example" @formatString = private constant [15 x i8] c"Hello, %s!\n\00" declare i32 @printf(i8*, ...) define i32 @main(i32 %argc, i8** %argv) { entry: %str = getelementptr [15 x i8], [15 x i8]* @formatString, i32 0, i32 0 %call = call i32 (i8*, ...) @printf(i8* %str, i8* %argv) ret i32 0 } ``` --- ``` ; ModuleID = 'example' source_filename = "example" ``` LLVM IR 檔案的元數據(Metadata) 它們指定了模組的 ID 和來源檔案的名稱 --- ``` @formatString = private constant [15 x i8] c"Hello, %s!\n\00" ``` 聲明一個私有的常數 formatString,它是一個包含字串 "Hello, %s!\n" 的字元陣列 [15 x i8] 表示這是一個長度為 15 的字元陣列 c"Hello, %s!\n\00" 表示這是一個以字元串形式表示的常數 --- ``` declare i32 @printf(i8*, ...) ``` 聲明一個外部函式 printf,它接受一個 i8*(指向字元的指標)作為參數,並具有變參(variadic)參數列表 --- ``` define i32 @main(i32 %argc, i8** %argv) { ``` 定義 main 函式,它接受兩個參數 argc 和 argv,其中 argc 是一個整數,argv 是一個指向指向字元的指標的指標(C 語言中的命令列參數) --- ``` entry: ``` 標記一個基本區塊(Basic Block)的起始點,它的名稱是 entry --- ``` %str = getelementptr [15 x i8], [15 x i8]* @formatString, i32 0, i32 0 ``` 這一行使用 getelementptr 指令,計算 formatString 字串的位址。 它的第一個參數 [15 x i8] 是源陣列的類型 第二個參數 [15 x i8]* @formatString 是源陣列的指標 第三個和第四個參數 i32 0 是計算索引值的偏移量,這裡都是 0,表示獲取第一個元素的位址 ``` %call = call i32 (i8*, ...) @printf(i8* %str, i8* %argv) ``` 這一行使用 call 指令呼叫 printf 函式 i32 是呼叫的返回值類型,(i8*, ...) 是函式的參數列表類型 @printf 是函式的名稱 i8* %str 和 i8* %argv 是實際的參數,分別將 %str 和 %argv 傳遞給 printf 函式 --- ``` ret i32 0 ``` 使用 ret 指令返回整數值 0 這表示 main 函式的執行結束並返回 0,這通常用於表示程式正常結束 ## 來源 > https://chat.openai.com/?model=text-davinci-002-render-sha