輸入以 0 結尾的字符串,將其中小寫字母轉大寫輸出,非字母字符原樣輸出。
PUSH DS / POP DS 破壞段寄存器,導致後續訪問錯誤。INT 21H AH=2 輸出字符後未正確循環判斷結束條件。N: 與 BEGIN: 跳轉邏輯混亂。0 (應為 '$' 或 0 視調用約定)。DATA SEGMENT
STR1 DB 'iamAstudent', 0 ; 以 0 結尾
PROMPT DB 'Result: $'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA
START:
MOV AX, DATA
MOV DS, AX
MOV ES, AX ; 顯示設置 ES=DS
LEA SI, STR1 ; SI 指向字符串
LEA DX, PROMPT
MOV AH, 09H
INT 21H ; 顯示提示
NEXT_CHAR:
MOV AL, [SI] ; 讀取字符
INC SI
CMP AL, 0 ; 遇到 0 結束
JE EXIT
CMP AL, 'a'
JB PRINT_CHAR ; 小於 'a' 直接輸出
CMP AL, 'z'
JA PRINT_CHAR ; 大於 'z' 直接輸出
SUB AL, 20H ; 小寫轉大寫 (a=61H, A=41H, 差 20H)
PRINT_CHAR:
MOV DL, AL
MOV AH, 02H
INT 21H ; 輸出字符
JMP NEXT_CHAR
EXIT:
MOV AH, 4CH
INT 21H ; 返回 DOS
CODE ENDS
END START
| 原問題 | 修正 |
|---|---|
| 段寄存器亂動 | 程序開始設置 MOV ES, AX,輸出過程不再修改 DS/ES |
| 結束判斷 | CMP AL, 0 / JE EXIT 統一在讀取後立即判斷 |
| 轉換邏輯 | SUB AL, 20H 只有在 'a'..'z' 範圍內執行 |
| 輸出調用 | 統一用 MOV DL, AL / MOV AH, 02H / INT 21H |
| 循環結構 | 單一入口 NEXT_CHAR:,清晰無雜亂跳轉 |
Result: IAMASTUDENT
INPUT_LOOP:
MOV AH, 01H ; 帶回顯輸入
INT 21H ; AL = 輸入字符
CMP AL, 0DH ; 回車鍵結束
JE PROCESS
MOV [SI], AL
INC SI
JMP INPUT_LOOP
PROCESS:
MOV BYTE PTR [SI], 0 ; 添加結束符 0
; 接上述轉換輸出邏輯
DEBUG 或 TD (Turbo Debugger) 單步跟蹤 SI、AL、FLAGS。INT 21H 觀察輸出。DS:SI 確認字符串正確存放。彙編語言核心:**寄存器管理規範**、**循環結構清晰**、**段地址正確**。本例通過統一讀取-判斷-轉換-輸出流程,修復了原代碼的段寄存器破壞與邏輯跳轉混亂。