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

8086組合語言實作:簡易系統時間顯示程式

     編輯:組合語言

前言:DOS 時代的時間獲取

在現代作業系統中,獲取系統時間只需呼叫高階 API 即可。但在 16 位元的 DOS 時代,程式設計師必須直接與硬體互動,透過 BIOS 或 DOS 中斷服務來取得即時時鐘資料。這篇文章將帶您深入解析一段經典的 8086 組合語言程式碼,展示如何使用 DOS 21h 中斷的 2Ch 功能獲取時間,並將二進位數值轉換為可讀的 ASCII 字元顯示在螢幕上。

核心邏輯:中斷 21h 功能 2Ch

程式的進入點位於 start 標籤。首先呼叫 int 21h 並將 AH=2Ch,這會從系統即時時鐘讀取當前時間:

  • CH = 小時 (0-23)
  • CL = 分鐘 (0-59)
  • DH = 秒數 (0-59)
  • DL = 百分之一秒

取得原始數值後,程式呼叫 disptime 子程序依序處理時、分、秒三個欄位,每個欄位都透過 bindec 子程序將二進位數值轉換為兩位十進位 ASCII 碼,中間插入冒號分隔。

關鍵子程式:BINDEC 二進位轉十進位 ASCII

bindec 是此程式的精華。它接收 AL 中的 8 位元數值,先用 CBW 擴展為 16 位元 AX,然後反覆除以 10 取得商與餘數:

mov dx, 0       ; 被除數高 16 位歸零
mov cx, 10d     ; 除數為 10
div cx          ; AX = 商, DX = 餘數

商代表十位數,餘數代表個位數。兩者分別加上 30h 轉為 ASCII 碼('0' 至 '9'),再透過 int 21h 功能 02h 輸出字元。子程式妥善保存/恢復 AX, CX, DX 寄存器,展現良好的模組化設計習慣。

完整原始碼賞析

code segment
assume cs:code
start:
mov ah,2ch ; 2Ch 功能:取系統時間 → CH=時, CL=分, DH=秒
int 21h
call disptime ; 顯示時間
exit:
mov ax,4c00h ; 4Ch 功能:結束程式返回 DOS
int 21h
disptime proc
mov al,ch ; 處理小時
cbw ; AL 擴展為 AX
call bindec ; 轉換並顯示兩位數
mov dl,':' ; 輸出冒號
mov ah,02h
int 21h
mov al,cl ; 處理分鐘
cbw
call bindec
mov dl,':'
mov ah,02h
int 21h
mov al,dh ; 處理秒數
cbw
call bindec
ret
disptime endp
bindec proc
push ax ; 保存暫存器
push cx
push dx
mov dx,0
mov cx,10d
div cx ; 除以 10,商在 AL,餘數在 DL
mov bx,dx ; 暫存餘數 (個位)
mov dl,al ; 顯示商 (十位)
add dl,30h
mov ah,02h
int 21h
mov dx,bx ; 恢復餘數\n /> add dl,30h ; 轉 ASCII\n /> mov ah,02h\n /> int 21h\n /> pop dx ; 恢復暫存器\n /> pop cx\n /> pop ax\n /> ret\n />bindec endp\n />code ends\n />end start

技術亮點總結

  • 善用 CBW 指令進行位元擴展,簡化除法運算前置作業。
  • 採用堆疊保存暫存器,確保子程式不破壞呼叫端環境。
  • 模組化設計:disptime 負責流程控制,bindec 專司數值轉換,職責分離清晰。
  • 直接操作 DOS 中斷與螢幕輸出,無需 C 執行期庫,程式極其精簡(僅約 50 位元組)。

現代視角的啟發

雖然現代開發鮮少撰寫裸機組合語言,但這段程式碼示範了「資源受限環境下的極致優化」:無系統呼叫開銷、無執行期依賴、直接控制硬體。這種思維在嵌入式韌體、Bootloader、效能關鍵路徑優化中依然極具價值。理解二進位與 ASCII 轉換、中斷呼叫慣例、暫存器保存協定,更是逆向工程與安全研究的基石能力。

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