首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

內聯彙編入門:判斷輸入格式是否為「數字+字母 a」的思路與實現

     編輯:程式設計綜合問答

需求場景

在 C 語言內聯彙編中,需判斷用戶輸入字符串是否符合「一個或多個數字後跟單個字母 'a'」模式(如 1a、20a、100a)。

核心思路:字符逐位掃描 + 狀態機

彙編無正則引擎,需手工實現字符級解析:

  1. 加載地址: 將字符串首地址載入寄存器(如 ESI/RDI)。
  2. 數字階段: 循環讀取字符,判斷 '0' <= ch <= '9'(CMP + JL/JG),非數字則跳轉失敗;計數器累加數字位數。
  3. 字母階段: 讀取下一字符,判斷 ch == 'a' || ch == 'A'。
  4. 終止檢查: 後續必須為 \0(字符串結束),否則格式錯誤。
  5. 設置標誌: 成功置 EAX=1,失敗置 EAX=0,返回 C 語言。

關鍵指令片段 (x86_64 AT&T 語法示例)

__asm__ (
    "mov %1, %%rdi\n"          // 字符串指針 -> RDI
    "xor %%rax, %%rax\n"       // RAX=0 (預設失敗)
    "xor %%rcx, %%rcx\n"       // RCX=0 (數字計數)
"1:\n"
    "movb (%%rdi), %%al\n"     // 讀取字符
    "test %%al, %%al\n"        // 檢查 \0
    "je 2f\n"                  // 過早結束 -> 失敗
    "cmpb $'0', %%al\n"
    "jl 2f\n"
    "cmpb $'9', %%al\n"
    "jg 3f\n"                  // 非數字,進入字母檢查
    "inc %%rdi\n"              // 指針後移
    "inc %%rcx\n"              // 數字計數++
    "jmp 1b\n"                 // 繼續掃描數字
"3:\n"
    "cmpb $'a', %%al\n"
    "je 4f\n"
    "cmpb $'A', %%al\n"
    "jne 2f\n"                 // 非 a/A -> 失敗
"4:\n"
    "inc %%rdi\n"
    "movb (%%rdi), %%al\n"     // 檢查下一字符必須為 \0
    "test %%al, %%al\n"
    "jne 2f\n"
    "cmp $1, %%rcx\n"          // 至少一位數字
    "jl 2f\n"
    "mov $1, %%rax\n"          // 成功 RAX=1
"2:\n"
    : "=a" (result)            // 輸出
    : "r" (str)                // 輸入
    : "rdi", "rcx", "al", "memory" // 破壞寄存器
);

工程化建議

  • 優先用 C 庫函數: sscanf(str, \"%d%c\", &num, &ch) == 2 && ch == 'a' 可讀性高、編譯器優化好、跨平台。
  • 必須內聯彙編時: 封裝為獨立函數,添加詳細註釋,編寫完整單元測試覆蓋邊界(空串、純數字、多字母、大小寫)。
  • 避免硬編碼偏移: 使用編譯器內建變量(%0, %1)綁定 C 變量,而非硬編碼棧偏移。

內聯彙編是「核武器級」工具,僅在極致性能、硬件交互或教學驗證時使用;日常字符串解析,C 標準庫才是正道。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved