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

MASM 16 位元二進制減法模擬教學範例

     編輯:組合語言

前言

這是一個經典的 MASM 5.0 教學範例,示範如何純粹用組合語言指令模擬 16 位元有號二進制整數減法運算,包含原碼/補碼轉換、逐位減法、借位處理、結果轉十六進位顯示。適合初學者理解電腦底層算術運算原理。

程式功能流程

  1. 輸入兩組 16 位元二進制字串 (原碼,最高位為號碼)
  2. 分別轉換為補碼表示
  3. 模擬補碼減法 (被減數補碼 + 減數補碼)
  4. 結果補碼轉回原碼
  5. 將 16 位元二進制結果轉為 4 位十六進位顯示

核心子程式分析

1. 補碼轉換

questBuma proc near
 mov al,[bx+0]; cmp al,'0'; jz qbret  ; 正數直接返回
 mov si,1
qbroat:                     ; 取反
 mov al,[bx][si]; cmp al,'0'; jz qb1
 mov al,'0'; mov [bx][si],al; jmp qb2
qb1: mov al,'1'; mov [bx][si],al
qb2: inc si; cmp si,16; jl qbroat
qnext:                      ; 加 1
 mov dh,1; mov si,15
qbincre:
 mov al,[bx][si]; sub al,'0'; add al,dh; mov dh,0
 cmp al,2; jnz qbi1; mov al,0; mov dh,1
qbi1: add al,'0'; mov [bx][si],al
 dec si; cmp si,0; jnl qbincre
qbret: ret
questBuma endp

演算法:符號位不變,數值位取反加一。使用字元 '0'/'1' 運算,DH 作為進位旗標。

2. 16 位元減法模擬

bsubproc proc near
 push ax bx cx si
 mov bx,0; mov si,15       ; BX=借位旗標, SI=最低位索引
broat:
 mov al,num1[si]; add al,bh; mov bh,0
 cmp al,num2[si]; jnl bnext
 add al,2; dec bh          ; 借位處理
bnext: sub al,num2[si]; add al,'0'; mov sum[si],al
 dec si; cmp si,0; jnl broat
 pop si cx bx ax; ret
bsubproc endp

從最低位 (索引 15) 向最高位 (索引 0) 迴圈。BH 保存借位 (0 或 -1)。若被減數位 < 減數位,則被減數位 +2 (借位),設 BH=-1 供下一位使用。

3. 二進制轉十六進位

BinaryToHexAndOut proc near
 mov dh,2; mov si,0
bth1: mov al,0; mov di,0
bth2: mul dh; add al,[bx][di]; sub al,'0'; inc di; cmp di,4; jl bth2
 cmp al,9; jna bth3; sub al,10; add al,'A'; jmp bth4
bth3: add al,'0'
bth4: mov hexsum[si],al; inc si; add bx,4; cmp si,4; jl bth1
 ret
BinaryToHexAndOut endp

每 4 位一組 (共 4 組),以加權法計算十六進位值:AL = b3*8 + b2*4 + b1*2 + b0 (此處 DH=2,MUL DH 相當於左移 1 位,累加 4 次)。結果 0-9 → '0'-'9',10-15 → 'A'-'F'。

執行範例輸出

binary(YuanMa) num1=1000000000001011 ; 被減數原碼 (-11)
binary(YuanMa) num2=1000000000001101 ; 減數原碼 (-13)
binary(Buma) num1 BM=1111111111110101 ; 被減數補碼
binary(Buma) num2 BM=1111111111110011 ; 減數補碼
binary(Buma) diff sub=0000000000000010 ; 差補碼 (+2)
binary(YuanMa)diffsub=0000000000000010 ; 差原碼 (+2)
hex sumHEX=0002

驗證:(-11) - (-13) = +2,結果正確。

教學價值與不足

優點說明
原理透明逐步展示補碼轉換、減法邏輯、進制轉換
字元級操作直接處理 ASCII '0'/'1',直觀易懂
模組化三個獨立 PROC,結構清晰
缺點/改進說明
效率低未善用 CPU 算術指令 (SUB, SBB, DAA 等)
錯誤處理簡陋輸入非 0/1 直接重輸,無提示
溢位未檢查16 位有號減法可能溢位 (OF),未處理
硬編碼緩衝區固定 19/5 位元組,缺乏邊界檢查

結語

這個範例雖然不具實用性 (CPU 內建減法指令遠快於模擬),但作為教學工具極為優秀。它將「黑盒子」指令拆解為可視的位元操作,幫助初學者建立「補碼減法 = 加法器 + 取反 + 1」的硬體視角。對於進階學習,可嘗試改寫為使用 SBB (帶借位減法)、DAA (十進位調整)、查表法轉十六進位等優化版本,體會指令集設計的精妙。

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