IA-32彙編語言筆記(15)—— intel風格全彙編示例(軟件實驗部分)

  • 記錄彙編語言課筆記,可能有不正確的地方,歡迎指出
  • 教材《80X86微機原理及接口技術實驗指導書》
  • 這篇文章是書中部分軟件實驗代碼的總結,可以用Tdpit 環境編譯並運行在配套實驗箱中(本文中給出的軟件實驗代碼實際上不需要實驗箱的硬件資源),這個環境支持比較標準的intel風格彙編,我估計在masm編譯器中也能便宜運行。
  • 下一篇文章將給出一些硬件實驗的示例
  • 後面我會發一些基於nasm編譯器的全彙編代碼,nasm也支持intel風格全彙編,但是在語法上稍微有點區別,將來發出來後可以和這裏的代碼對比看
  • nasm和masm的區別

一、軟件實驗

  • 實驗中所使用DOS 功能調用( INT 21H )說明如下
    1. 2號功能:顯示單個字符輸出
      入口:AH=02H
      調用參數:DL= 輸出字符
    2. 9號功能:顯示字符串
      入口:AH=09H
      調用參數:DS:DX= 串地址,’$'爲結束字符
    3. 10號功能:鍵盤輸入
      入口:AH=0 A H
      調用參數:DS:DX= 輸入緩衝區地址, 首字節爲緩衝區字節長度,第二字節爲實際輸入的字符計數
    4. 4ch號功能:返回 DOS 系統
      入口:AH=4CH
      調用參數:AL= 返回碼

1. 四則運算

(1)實驗要求

完成 32 位無符號數的加法、減法,16 位乘以 16 位,32 位除以 16 位除法的四則運算練習。

(2)原理提要

  1. 字節序
    字節序分爲大端模式(Big-Endian)和小端模式(Little-Endian),定義如下:
    1. Little-Endian 就是低位字節排放在內存的低地址端,高位字節排放在內存的高地址端。
    2. Big-Endian 就是高位字節排放在內存的低地址端,低位字節排放在內存的高地址端。
      例如:32bit 寬的數 0x12345678 在小端模式以及大端模式 CPU 內存中的存放方式(假
      設從地址 0x4000 開始存放)爲:
      在這裏插入圖片描述
  1. x86架構是小端存儲的,注意下面代碼A DW 1234H, 5678H ;被加數,可以看到這一句定義了連續的兩個字數據,數據地址按先後順序由低到高排列,又因爲每一個字在存儲時按找小段存儲規則,所以它在內存中的存儲情況時34 12 78 56,解釋稱十六進制數就是0x56781234

(3)代碼示例

DATA SEGMENT
	A DW 1234H, 5678H 	;被加數		32位數分兩個16位存 56781234H
	B DW 0FEDCH, 123AH 	加數		32位數分兩個16位存 FEDC123AH
	C DW 2 DUP (?)		;預留和		留兩個雙字(16位)空間存加法結果
	AD DW 0FEDCH, 0BA98H;被減數		BA98FEDCH
	BD DW 1234H, 789AH 	;減數		789A1234H
	CD DW 2 DUP (?) 	;預留差
	A1 DW 0D678H 		;被乘數		
	B1 DW 0012H 		;乘數
	C1 DW 2 DUP (?) 	;預留積
	A2 DW 5678H, 0234H 	;被除數		02345678	
	B2 DW 0F234H 		;除數		F234
	C2 DW 2 DUP (?) 	;預留商,餘數
DATA ENDS

STACK1 SEGMENT STACK 
	;DB 100 DUP(?)     
	buffer db 100 dup(0)
STACK1 ENDS

CODE SEGMENT
	ASSUME CS:CODE,DS:DATA,SS:STACK1
	
START PROC FAR
	;標準序
	PUSH DS
	MOV AX, 0 		
	PUSH AX 
	MOV AX, DATA
	MOV DS, AX
	
	;32+32位	結果68B31110H
	MOV AX, A		
	ADD AX, B
	MOV C, AX	;16位加完存在C,進位在CF
	MOV AX, A+2 	
	ADC AX, B+2	;ADC帶進位加,處理高16位,存在C+2
	MOV C+2, AX
	
	;32-32位	結果41FEECA8H	
	MOV AX, AD
	SUB AX, BD
	MOV CD, AX
	MOV AX, AD+2
	SBB AX, BD+2
	MOV CD+2, AX
	
	;16位乘16位	結果000F1470H
	MOV AX, A1
	MOV BX, B1
	MUL BX
	MOV C1, AX
	MOV C1+2, DX
	
	;32位除16位	結果254H..7568H
	MOV DX, A2+2
	MOV AX, A2
	MOV BX, B2
	DIV BX
	MOV C2, AX		;商在AX
	MOV C2+2, DX	;餘數在DX
	
	RET
START ENDP

CODE ENDS
	END START
  • 在emu8086中運行並查看內存,可以觀察到計算結果
    在這裏插入圖片描述

2. 數據統計

(1)實驗任務

  • 本實驗要求通過求某數據區內負數的個數來表現循環程序的結構形式。要求實驗程序在數據段
    中存放一組數據,分類統計數據中正數、負數和零的個數,並分別存入內存變量 Positive、Negative
    和 Zero 中。將所有數據累加求和,存入 SUM 中。

(2)參考代碼

  • 主要邏輯代碼
;宏函數,輸出回車
CRLF MACRO 
    MOV DL, 0DH
    MOV AH, 02H 	;INT21的2號功能(單個字符輸出)
    INT 21H
    MOV DL, 0AH 
    MOV AH, 02H
    INT 21H     	;連續輸出0DH和0AH,顯示回車
ENDM

DATA SEGMENT
	NUM DB 12H,88H,82H,89H,33H,90H,0H,10H,0BDH,01H  ;108位數據
	Positive DB DUP (0)                     		;正數個數 4
	Negative DB DUP (0)                          	;負數個數 5
	Zero DB DUP (0)                                 ;0個數    1
	SUM DW 2 DUP (0)                                ;總和   
     
	MESP DB 'Positive number:$'
	MESN DB 'Negative number:$'
	MESZ DB 'Zero number:$' 
	MESS DB 'Sum = $'   
	
	result DB 0,0,'$'
DATA ENDS

STACK1 SEGMENT STACK 
    ;DB 100 DUP(?)
    buffer db 100 dup(0)
STACK1 ENDS    

CODE SEGMENT
    ASSUME CS:CODE,DS:DATA,SS:STACK1  				;設置段寄存器
    
START PROC FAR 
	PUSH DS 
	MOV AX, 0 
	PUSH AX 
	MOV AX, DATA 
	MOV DS, AX 
	
	MOV CX,10 		;循環10次 
	LEA SI,NUM 
	MOV BX,0 
LAB1:
	MOV DL,[SI] 
	CMP DL,0 		;判斷num是否爲0 
	JG LAB2 		;num>0,跳轉到LAB2 
	JL LAB3 		;num<0,跳轉到LAB3 
	INC ZERO 		;num=0,ZERO加1 
	JMP LAB4 
LAB2:
	INC Positive 	;負數+1 
	JMP LAB4 
LAB3:
	INC Negative 	;正數+1 
LAB4:
	MOV AL,[SI] 
	CBW 			;符號拓展,8位拓展爲16位 
	ADD SUM,AX 		;+sum 
	ADC [SUM+2],0 
	INC SI 
	LOOP LAB1 		;循環 
	RET 
START ENDP 

CODE ENDS 
	END START
  • 觀察內存:
    在這裏插入圖片描述

  • 顯示部分代碼 (利用int 21h的9號功能)

MOV DX,OFFSET MESP 		;顯示“Positive number:”提示
MOV AH,9 
INT 21H 

MOV BL,Positive 		;取字節變量positive
MOV AL,BL 
SHR AL,4 
CALL ToASCII 			;把高四位轉換爲對應的ASCII碼 

MOV [result],AL 
MOV AL,BL 
CALL ToASCII 			;把低四位轉換爲對應的ASCII碼 

MOV [result+1],AL 
MOV DX,OFFSET result 
MOV AH,9 
INT 21H 

ToASCII PROC 
	AND AL,0FH 
	ADD AL,'0' 
	CMP AL,'9' 
	JBE LAB5 
	ADD AL,7 
LAB5: 
	RET 
ToASCII ENDP

3. 代碼轉換

(1)實驗任務

  • 從鍵盤輸入小寫字母(最多 20 個),以 “.”號作爲結束標誌, 將其變換成相應的大寫字母輸岀
    在屏幕上。

(2)原理提要

  • 輸入小寫字母用 INT 21 的 0AH 號功能,將讀入的數據存放在緩衝區 SMALL 中,其中 SMALL
    的笫一個字節指岀緩衝區能容納的字節數,不能爲 0(程序暫定爲 50),第二個字節保留,以用作存放
    實際鍵入的輸入字符的個數;從笫三個字節開始存放從鍵盤上輸入字符的 ASCII 碼,所以轉換時要
    從 SMALL 的笫三個字節,即 SMALL+2 開始。

  • SMALL 中存放的是小寫字母的 ASSII 碼,將此值減去 20H,即爲大寫字母的 ASSII 碼,將其依次
    存放在名爲 CAPITAL 的數據段中,然後用 INT 21 中的 09H 功能輸出。

(3)參考代碼

CRLF MACRO
    MOV DL, 0DH
    MOV AH, 02H 		;INT21的2號功能(單個字符輸出)
    INT 21H
    MOV DL, 0AH 
    MOV AH, 02H
    INT 21H     		;連續輸出0DH和0AH,顯示回車
ENDM      

DATA SEGMENT
	MES1 DB 'PLEASE INPUT THE SMALL LETTER,ENDED WITH ".":$'
	MES2 DB 'THE CAPTAL LETTER IS:$'
	SMALL DB 50             ; 預留鍵盤輸入緩衝區長度爲50個
    	  DB 0              ; 預留實際鍵盤輸入字符數的個數
   	 	  DB 50 DUP(0)      ; 存放輸入符號串的位置  
    
	CAPITAL DB 50 DUP(0)    ; 預留大寫字母緩衝區長度爲50個
DATA ENDS 

STACK1 SEGMENT STACK
    DB 100 DUP (0)
STACK1 ENDS  

CODE SEGMENT
    ASSUME CS:CODE,DS:DATA,SS:STACK1  
    
START PROC FAR
    PUSH DS
    MOV AX, 0
    PUSH AX
    MOV AX, DATA
    MOV DS, AX          ;數據段DS指向DATA  
    
    MOV AH, 9           ;INT21的9號功能(輸出)
    LEA DX, MES1        ;輸出信息位置
    INT 21H             ;輸岀提示信息MES1
    
    CRLF                ;宏調用,輸出回車
    
    MOV AH, 0AH         ;INT21的10號功能(輸入)
    LEA DX, SMALL       ;輸入信息緩存位置    
    ;INC DX
    INT 21H             ;接收小寫字符串   
    
    CRLF                ;宏調用,輸出回車
            
    
    ;轉換部分利用INT21的10號功能得到的字符串長度實現,沒有考慮超長問題
    ;LEA SI,SMALL
    ;LEA DI,CAPITAL
    ;XOR CH,CH           ;CL中存儲循環次數,注意最後輸入的.不算
    ;MOV CL,[SI+1]
    ;ADD SI,2            ;指向真正輸入數據 
    ;DEC CL
 ;LOOPSIGN:				;循環cx次,把小寫字符轉大寫存入CAPITAL
    ;MOV AL,[SI]
    ;SUB AL,20H
    ;MOV [DI],AL
    ;INC DI
    ;INC SI 
    ;LOOP LOOPSIGN
	   
	;轉換時利用句號判斷終止時機,進行了長度限制,比上面那個好
	LEA BX, SMALL+2 
	LEA DI, CAPITAL 
	MOV CX, 20 			;最多20個字符 
LAB: 
	MOV AL, [BX] 
	CMP AL, 2EH 		;是否遇到句號. 
	JE KE 
	SUB AL, 20H 		;轉爲大寫,ASCLL-20H 
	MOV [DI], AL 
	INC BX 
	INC DI 
	LOOP LAB


KE: 
	MOV AL, '$'     	;大寫字符串後加“$”
    MOV [DI], AL
    
    MOV DX, OFFSET MES2 ;輸岀提示信息MES2
    MOV AH, 9
    INT 21H   
    
    CRLF                ;宏調用,輸出回車
    
    MOV DX, OFFSET CAPITAL 
    MOV AH, 9           ;輸岀大寫字符串
    INT 21H                 
    
    RET          
    
START ENDP
CODE ENDS
    END START
  • 軟件部分代碼到此結束,下一篇文章給出一些硬件實驗相關的代碼
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章