NASM 與 GDB 簡易除錯指南

乾坤盘發表於2024-08-27

本文目標:在 Linux 平臺中,利用 nasm 與 gdb 快速構建一個編譯與除錯工具鏈,以下僅做簡單演示。
主要還是因為學習“計算機組成原理”中 intel 指令相關內容的時候,太生澀難懂了。就是想簡單實操一下,深刻理解,因此才出了這篇文章。

我們以一下程式為例舉例說明。

section .data
    hello db "hello, world", 10 ; 定義要輸出的字串,10 是換行符的 ASCII 碼
    hello_len equ $ - hello ; 計算字串長度

section .text
    global _start ; 必須宣告 _start 為全域性符號,這是連結器識別的入口點


; 呼叫系統呼叫 exit
exit:
    mov rax, 1 ; 系統呼叫號,這裡是 exit
    int 0x80 ; 觸發系統呼叫

; 一個簡易的加法函式
; 傳參暫存器 edi, esi
add:
    push rbp
    mov rbp, rsp
    ; 函式無變數
    mov [rbp - 4], edi
    mov [rbp - 8], esi
    mov edx, [rbp - 4]
    mov eax, [rbp - 8]
    add eax, edx
    pop rbp
    ret

; 入口函式   
_start:
    ; 呼叫系統呼叫 write 功能, 向終端輸出文字
    mov eax, 4 ; 系統呼叫號,這裡是 write
    mov ebx, 1 ; 檔案描述符 1,代表標準輸出
    mov ecx, hello ; 字串的地址
    mov edx, hello_len ; 字串長度
    int 0x80 ; 觸發系統呼叫

    mov edi, 10
    mov esi, 20
    call add
    mov rbx, rax
    jmp exit

如何使用 NASM 編譯生成可執行檔案

在 Linux 平臺上,我們可以直接使用 nasm 生成 elf 可執行檔案,目前 nasm 提供了兩種生成方法。

  1. 生成可重定向目的碼,然後再連結程式碼。

    nasm -f elf64 test.asm -o test.o
    ld -o test test.o
    
  2. 直接生成可執行檔案。

    nasm -f aout test.asm -o test
    

如何使用 GDB 除錯生成的程式碼

由於我們生成的程式碼並不可能包含除錯資訊,以至於我們在除錯的時候困難重重。我們只能使用 disassemble 指令來檢視除錯內容。

gdb ./test	# 執行指令
# 以下是互動式介面需要執行的命令
break _start	# 在 _start 處新增短點資訊
run	# 執行程式
layout asm	# TUI顯示彙編資訊
layout regs	# TUI顯示暫存器資訊

以下是一些常用命令:

  • info registers:檢視所有暫存器資訊
  • stepi:單次執行一條指令
  • continue:繼續執行指令
  • break *0x401016:在指定記憶體位置新增端點
  • x /10x $sp - 16:檢視 esp - 16 所在記憶體的連續 10 個 dword 大小的記憶體空間資料。

除錯的時候需要注意位數(64 位佔 8 位元組),以及intel處理器為小端方式

相關文章