今天要把昨天的第二種方法說完啦!!!
.arch armv8-a // 指定程式的架構為 ARMv8-A
.file "chall.c" // 設定檔案的名稱為 "chall.c"
.text // 開始定義程式碼區段
.align 2 // 對齊至 4 字節邊界(2^2 = 4
.global func1 // 將 func1 標記為全域符號,以便其他檔案引用
.type func1, %function // 指定 func1 的類型為函數
func1: // 函數 func1 的標籤
sub sp, sp, #16 // 在堆疊上分配 16 字節空間(這邊顏色我改不掉啊啊啊啊)
str w0, [sp, 12] // 將參數 w0 存入堆疊中偏移 12 的位置([sp+12] = w0)
str w1, [sp, 8] // 將參數 w1 存入堆疊中偏移 8 的位置
ldr w1, [sp, 12] // 從堆疊中加載偏移 12 的值到 w1
ldr w0, [sp, 8] // 從堆疊中加載偏移 8 的值到 w0
cmp w1, w0 // 比較 w1 和 w0 的值
bls .L2 // 如果 w1 ≤ w0,跳轉至標籤 .L2( Branch if Lower or Same
ldr w0, [sp, 12] // 加載偏移 12 的值到 w0(如果 w1 > w0)
b .L3 // 跳轉至標籤 .L3
.L2: // 標籤 .L2
ldr w0, [sp, 8] // 加載偏移 8 的值到 w0
.L3: // 標籤 .L3
add sp, sp, 16 // 恢復堆疊指標,釋放之前分配的 16 字節空間
ret // 返回調用者
.size func1, .-func1 // 設定 func1 的大小,為當前位置與 func1 標籤的偏移量
.section .rodata // 開始只讀數據區段
.align 3 // 對齊至 8 字節邊界(2^3 = 4
.LC0: // 字串標籤 .LC0
.string "Result: %ld\n" // 定義格式化字串 "Result: %ld\n"
.text // 再次開始程式碼區段
.align 2 // 對齊至 4 字節邊界
.global main // 將 main 標記為全域符號,以便其他檔案引用
.type main, %function // 指定 main 的類型為函數
main: // 函數 main 的標籤
stp x29, x30, [sp, -48]! // 保存鏈接寄存器 (x30) 和幀指標 (x29),並更新堆疊指標
add x29, sp, 0 // 將當前堆疊指標設置為幀指標 x29
str x19, [sp, 16] // 將寄存器 x19 的值存入堆疊中偏移 16 的位置
str w0, [x29, 44] // 將 w0 存入幀指標 x29 偏移 44 的位置
str x1, [x29, 32] // 將 x1 存入幀指標 x29 偏移 32 的位置
ldr x0, [x29, 32] // 從幀指標 x29 加載偏移 32 的值到 x0
add x0, x0, 8 // 將 x0 增加 8,為了獲取下個參數
ldr x0, [x0] // 加載 x0 指向的值到 x0(這應該是字符串)
bl atoi // 調用 atoi 函數將字符串轉換為整數
mov w19, w0 // 將結果存儲到 w19
ldr x0, [x29, 32] // 再次從幀指標 x29 加載偏移 32 的值到 x0
add x0, x0, 16 // 將 x0 增加 16,獲取第二個參數
ldr x0, [x0] // 加載 x0 指向的值到 x0(這是第二個字符串)
bl atoi // 調用 atoi 函數將字符串轉換為整數
mov w1, w0 // 將第二個參數的結果存入 w1
mov w0, w19 // 將第一個參數的結果存入 w0
bl func1 // 調用 func1 函數,傳入兩個參數
mov w1, w0 // 將 func1 的返回值存入 w1
adrp x0, .LC0 // 加載 .LC0 的頁面地址到 x0
add x0, x0, :lo12:.LC0 // 將 .LC0 的偏移加到 x0
bl printf // 調用 printf 輸出結果
mov w0, 0 // 將返回值設置為 0,表示正常退出
ldr x19, [sp, 16] // 從堆疊加載 x19 的值
ldp x29, x30, [sp], 48 // 恢復堆疊指標和鏈接寄存器
ret // 回到原本引用函式的地方
.size main, .-main // 設定 main 的大小,為當前位置與 main 標籤的偏移量
.ident "GCC: (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0" // 編譯器信息
.section .note.GNU-stack,"",@progbits // 設置 GNU 堆疊註釋
後記:
不知道各位有沒有發現,這篇有很多註解感覺不像我寫的,因為參考了GPT同學的解釋,不然我有好多都看不懂😭😭,像是.什麼的,我知道的就只有.text,我平常都在看ELF檔的換到這裡多了好多詭異的東東啊,我的.bss .data呢🫠🫠