匯編語言的編寫


匯編運行過程

准備

由於大多數win10系統都是64位系統,所以如果直接用link.exemasm.exe來運行asm文件是不可以的。

所以需要安裝DOSBox

dosbox.PNG

DOSBox,Link,Masm介紹

Link和masm

 masm32包即可以支持開發在DOS操作系統下運行的16位應用程序,也可以開發在Windows操作系統下運行的32位應用程序。

masm.exe——匯編器。我們編寫的源代碼文件就是通過它來匯編生成中間代碼文件,即通常擴展名為.obj的文件。
  link16.exe——連接器。由masm.exe匯編生成的.obj文件還不能直接上機運行,必須通過連接器link16.exe將其連接制作成擴展名為.exe(或者.com)的可執行文件才能上機。

但是我們主流的系統基本都是64位了,所以需要用DOSBox來給我們提供一個16位的DOS系統環境

DOSBox

在現在的系統下模擬DOS環境的一個工具!是為了運行以前純DOS環境下的軟件而開發的!當然主要用途是運行原來的那些只能在DOS下玩的老游戲!

使用方法:

  1. 將存放masm、link和源程序文件的文件夾拷貝到某一目錄下,比如c:\examples
  2. 然后將這個目錄掛為DOSBox的一個盤符下,掛載命令為
    Mount c c:\examples ; 可以理解為把當前工作目錄切換到c:\examples這里,即c:\examples就是你以后的C:
  3. 再切換到掛載的c盤:
    c: ; 切換到工作目錄

mount.PNG

開始寫程序

此次用到的文件

仔細對應DOSBox圖片里面的代碼和這個圖片里面的文件

produce.PNG

利用masm.exe生成.OBJ文件

在后綴名為.asm的文件中,編寫完代碼之后

DOSBox中利用masm.exe運行.asm文件

masm yourfile.asm ; 注意,可以不加.asm后綴.不加的時候要保持名字不重復

masm.PNG

利用link.exe運行.OBJ文件,生成.exe文件

DOSBox中利用link.exe運行.OBJ文件,然后生成.exe文件

link yourfile.OBJ  ; 注意,可以不加.OBJ后綴.不加的時候要保持名字不重復

link.PNG

這里有warning L4021是因為我在寫代碼的時候沒有定義堆棧區,但是沒有關系

系統自動會幫我們建立堆棧區

運行.exe文件

DOSBox中直接運行.exe文件.OBJ文件,然后生成.exe文件

exe.PNG

本次的代碼


DATA SEGMENT                        ;定義數據段
   STRING1 DB 'IT IS ODD!','$'
   STRING2 DB 'IT IS EVEN!','$'
DATA ENDS



CODE SEGMENT                        ;定義代碼段
 ASSUME CS:CODE,DS:DATA             ;ASSUME偽指令,說明段與段寄存器之間的對應關系
START:  
        MOV AX,DATA                 ;實現段與段寄存器之間的對應關系,代碼段系統會默認
        MOV DS,AX

        MOV AH,01H                  ;調用1號DOS功能,從鍵盤上讀入一個字符,並將該字符回顯在屏幕上
        INT 21H
        CLC
        RCR AL,1
        JNC EVN
        MOV DX,OFFSET STRING1       ;將字符串Sting1的偏移地址賦給DX
        CALL DISPMESS
EVN: MOV DX,OFFSET STRING2
     CALL DISPMESS
  
DISPMESS PROC                      ;定義一個過程,用於輸出字符串
     MOV AH,9                      ;調用9號子功能
     INT 21H                       ;返回DOS
     MOV AH,4CH                    ;結束程序
     INT 21H
DISPMESS ENDP

CODE ENDS
     END START

大作業

USE16的作用

這句指的是,數據段采取16位來存取數據段中的數據。如果use32則是指用32位來存取數據段中的數據。具體的16還是32,根據你編程面向的cpu類型是16位的還是32位的。
另外再補充一點點吧。
cpu將內部存儲單元分成許多邏輯段(Segment),這樣,一個存儲單元除具有一個唯一的物理地址外,還具有多個邏輯地址。
data segment 指的就是數據段。
數據段存放運行程序所用的數據。數據段寄存器DS存放數據段的段地址。各種主存尋址方式(有效地址EA)得到存儲器中操作數的偏移地址。處理器利用DS:EA存取數據段中的數據。

DATA		SEGMENT
	MESG1    DB    'USERNAME:',0DH,0AH,'$'  ;指定用戶名存放的數據區
	MESG2    DB    0DH,0AH,'PASSWORD:',0DH,0AH,'$'    ;指定密碼的數據區
	MESG3    DB    0DH,0AH,0DH,0AH,'Password Right!',0DH,0AH,'$' ;密碼正確提示
	MESG4    DB    0DH,0AH,0DH,0AH,'USERNAME Error!',0DH,0AH,'$';  ;用戶名報錯	
	MESG5    DB    0DH,0AH,0DH,0AH,'Password Error!',0DH,0AH,'$';  ;密碼報錯
	
	
	BUF1        DB    '2018633007'
	USERLEN      EQU    $-BUF1   ;統計用戶名長度
	BUF2        DB    '5201314'
	PWLEN      EQU    $-BUF2     ;統計密碼長度
	BUF3        DB    15               ;用戶輸入用戶名的數據區
				DB    ?
				DB    15    DUP(?)
	BUF4        DB    15    DUP(?)     ;用戶輸入密碼的數據區
DATA        ENDS


CODE	SEGMENT
		ASSUME    CS:CODE,DS:DATA
START:       
		MOV    AX,DATA
		MOV    DS,AX
		
		MOV    AH,9
		MOV    DX,OFFSET    MESG1		;顯示用戶名輸入界面
		INT    21H
		
		MOV    AH,0AH
		MOV    DX,OFFSET    BUF3		;鍵入用戶名字符串
		INT    21H
		
		MOV    BX,OFFSET    BUF1		;獲得儲存正確賬戶名的偏移地址
		MOV    SI,OFFSET    BUF3+2		;獲得儲存輸入賬戶名的偏移地址
		MOV    CX,USERLEN
	   
CMPUSER:	
		; 進行用戶名對比
		MOV    AL,[BX]
		CMP    [SI],AL				;將輸入字符串的對應位置與正確賬戶名進行比較
		JNZ    ERROR1				;當前位置和原本的用戶名不一樣就報錯
		INC    SI
		INC    BX
		LOOP   CMPUSER                   ;重復進行直到字符串結束
		MOV    AH,9
		MOV    DX,OFFSET    MESG2         ;顯示密碼輸入界面
		INT    21H
		MOV    CX,PWLEN				; 將正確的密碼長度讀入
		MOV    SI,OFFSET    BUF4	;獲得儲存輸入密碼的偏移地址 
		 
GETPW:   
		MOV		AH,7                        ;逐個字符輸入密碼,遇到回車結束輸入
		INT		21H
		CMP    AL,0DH		
		JZ	   NEXT
		CMP    AL,08H
		JE	   DELETE
		MOV    [SI],AL
		MOV    AH,2                       ;在屏幕上顯示*
		MOV		DX,'*'
		INT    21H
		INC    SI
		INC    BX 				; 統計輸入密碼的長度
		LOOP   GETPW
		
DELETE:
		CMP	   BX, 00H				; 如果刪除到第0個位置,再刪除就直接退出
		JZ	   EXIT
		DEC	   BX
		
		CALL   DELCODE
		MOV	   AH,2		;調用2號中斷,顯示空格,消除星號
		MOV	   DL,' '
		INT    21H
		MOV	   BYTE PTR [SI],00H
		DEC    SI
		CALL   DELCODE
		
		JMP    GETPW

NEXT:    
		MOV    CX,PWLEN
		MOV    BX,OFFSET    BUF2
		MOV    SI,OFFSET    BUF4
		 
NEXT3:   
		MOV    AL,[BX]
		CMP    [SI],AL
		JNZ    ERROR2
		INC    SI
		INC    BX
		LOOP    NEXT3              ;逐個字符比較BUF2和BUF4
		MOV    AH,9
		MOV    DX,OFFSET    MESG3
		INT    21H
		JMP    EXIT
		
DELCODE		PROC		
		; 刪除一個字符,即把光標向左移動一格
		MOV    AH,3		; 獲取光標位置
		INT	   10H
		MOV	   AH,2		;2號中斷:置光標位置
		SUB    DL,1		;列數減1,實現光標左移
		INT	   10H
		RET
DELCODE		ENDP

		 
ERROR1:   
		; 用戶名錯誤時報錯
		MOV    DX,OFFSET   MESG4 
		CALL   DISPMESS

	
ERROR2:
		; 密碼錯誤時報錯
		MOV    DX,OFFSET    MESG5
		CALL   DISPMESS


DISPMESS	PROC
		MOV    AH,9
		INT    21H
		JMP    EXIT
DISPMESS	ENDP


EXIT:    
		MOV    AH,4CH
		INT    21H

CODE	ENDS
END START


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM