組合語言(Assembly Language)是面向機器的程式設計語言。在組合語言中,用助記符(Memoni)代替機器指令的操作碼,用地址符號(Symbol)或標號(Label)代替指令或運算元的地址,如此就增強了程式的可讀性並且降低了編寫難度,象這樣符號化的程式設計語言就是組合語言,因此亦稱為符號語言。使用匯編語言編寫的程式,機器不能直接識別,還要由彙編程式或者叫組合語言編譯器轉換成機器指令。彙編程式將符號化的操作程式碼組裝成處理器可以識別的機器指令,這個組裝的過程稱為組合或者彙編。因此,有時候人們也把組合語言稱為組合語言。
工具/原料
Assembly Language Masm彙編編譯器
方法/步驟
開啟masm彙編編譯程式,新建一個masm原始檔指令碼。
DATAS SEGMENT
;此處輸入資料段程式碼
DATAS ENDS
STACKS SEGMENT
;此處輸入堆疊段程式碼
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
;此處輸入程式碼段程式碼
MOV AH,4CH
INT 21H
CODES ENDS
END START
在正文中輸入我們的程式程式碼,並將檔案命名為size.asm
B_P EQU BYTE PTR
W_P EQU WORD PTR
D_P EQU DWORD PTR
CODE SEGMENT
ASSUME CS:CODE,DS:CODE
ORG 100H
;主程式開始
NEWSTAR:
JMP STAR
EVEN
NUM1 DW 0,0
NUM2 DW 0,0
NUM3 DW 0,0
JGV4 DW 0,0
YSF LABEL WORD
YSF1 DB 0
YSF2 DB 0
JUV DB 0
UV DB 0
;使DS:SI指向第一有效字元
OVERS LABEL NEAR
CLD
PUSH AX
OVERS1:
LODSB
CMP AL,' '
JZ OVERS1
CMP AL,9
JZ OVERS1
DEC SI
CMP AL,13
POP AX
RET
;輸出一個製表符
TAB LABEL NEAR
MOV AL,9
JMP SHORT DISP
;輸出一個回車換行符
CRLF LABEL NEAR
MOV AL,13
CALL DISP
MOV AL,10
;顯示一個字元
DISP LABEL NEAR
PUSH AX
PUSH DX
MOV AH,2
MOV DL,AL
INT 21H
POP DX
POP AX
RET
;檢查是否為運算子
ISYSF LABEL NEAR
CLD
LODSB
CALL ISJJ
JZ ISYSF1
CALL ISII
JZ ISYSF1
DEC SI
ISYSF1:
RET
;檢查是否是加減運算
ISJJ LABEL NEAR
CMP AL,'+'
JZ ISYSF1
CMP AL,'-'
RET
;檢查是否為乘除運算
ISII LABEL NEAR
CMP AL,'*'
JZ ISYSF1
CMP AL,'/'
JZ ISYSF1
CMP AL,'\'
RET
;資料輸出
;CX=10 十進位制
;CX=16 十六進位制
DOUT LABEL NEAR
PUSH AX
PUSH BX
PUSH DX
PUSH BP
XOR BP,BP
DOUT1:
INC BP
PUSH AX
MOV AX,DX
XOR DX,DX
DIV CX
MOV BX,AX
POP AX
DIV CX
PUSH DX
MOV DX,BX
OR BX,AX
JNZ DOUT1
DOUT2:
POP AX
ADD AL,'0'
CMP AL,'9'
JBE DOUT3
ADD AL,'A'-'9'-1
DOUT3:
CALL DISP
DEC BP
JNZ DOUT2
POP BP
POP DX
POP BX
POP AX
RET
;輸入資料在DX:AX中返回
;CX=0 資料為10進位制
;CX#0 資料為16進位制
DATE LABEL NEAR
PUSH BX
PUSH BP
PUSH DI
XOR AX,AX
XOR DX,DX
DATE1:
MOV DI,AX
LODSB
CMP AL,'0'
JB DATE7
CMP AL,'9'
JA DATE6
DATE2:
AND AX,0FH
SHL DI,1
RCL DX,1
MOV BX,DI
MOV BP,DX
SHL DI,1
RCL DX,1
SHL DI,1
RCL DX,1
JCXZ DATE3
SHL DI,1
RCL DX,1
Jmp short DATE4
DATE3:
ADD DI,BX
ADC DX,BP
DATE4:
ADD AX,DI
ADC DX,0
JMP DATE1
DATE5:
ADD AL,9
JMP DATE2
DATE6:
JCXZ DATE7
CMP AL,'A'
JB DATE7
CMP AL,'F'
JBE DATE5
CMP AL,'a'
JB DATE7
CMP AL,'f'
JBE DATE5
DATE7:
MOV AX,DI
DEC SI
OR DI,DX
POP DI
POP BP
POP BX
RET
;資料1與資料2根據YSF1進行加減運算
JSJJ LABEL NEAR
MOV AX,NUM2
MOV DX,NUM2+2
CMP YSF1,'+'
JZ JSJJ1
SUB NUM1,AX
SBB NUM1+2,DX
JMP SHORT JSJJ2
JSJJ1:
ADD NUM1,AX
ADC NUM1+2,DX
JSJJ2:
RET
;資料1與資料2根據YSF1進行乘除運算
JSII1 LABEL NEAR
MOV BX,OFFSET NUM1
JMP SHORT JSII2_1
;資料2與資料3根據YSF2進行乘除運算
JSII2 LABEL NEAR
MOV BX,OFFSET NUM2
JSII2_1:
DB 66H
MOV AX,[BX]
DB 66H
MOV CX,[BX+4]
CMP YSF2,'*'
JNZ JSII2_2
DB 66H
IMUL CX
JMP SHORT JSII2_3
JSII2_2:
DB 66H
CWD
DB 66H
IDIV CX
CMP YSF2,'/'
JZ JSII2_3
DB 66H
XCHG DX,AX
JSII2_3:
DB 66H
MOV [BX],AX
RET
;顯示結果
XUJG LABEL NEAR
MOV AX,JGV4
MOV DX,JGV4+2
MOV CX,10
CMP UV,10
JZ XUJG0
MOV CX,16
XUJG0:
TEST DX,8000H
JZ XUJG1
CMP UV,10
JZ XUJG2
CALL DOUT
XUJG2:
NOT AX
NOT DX
ADD AX,1
ADC DX,0
PUSH AX
CMP UV,10
JZ XUJG3
MOV AL,' '
CALL DISP
MOV AL,'('
CALL DISP
XUJG3:
MOV AL,'-'
CALL DISP
POP AX
CMP UV,10
JZ XUJG1
CALL DOUT
MOV AL,')'
CALL DISP
RET
XUJG1:
CALL DOUT
RET
;計算結果放入DX:AX中
JSJG LABEL NEAR
CALL JSJJ
MOV AX,NUM1
MOV DX,NUM1+2
RET
;從DS:SI處取一個數據
LOADATE LABEL NEAR
LODSB
CMP AL,'('
JZ LOADATE1
DEC SI
PUSH CX
XOR CX,CX
CMP UV,10
JZ LOADATE0
INC CX ;取16進位制數
LOADATE0:
CALL DATE ;取資料放入DX:AX中
POP CX
RET
LOADATE1:
PUSH NUM1 ;儲存資料1資料2及運算子
PUSH NUM1+2
PUSH NUM2
PUSH NUM2+2
PUSH YSF
INC JUV
MOV JGV4,0 ;結果值清零
MOV JGV4+2,0
;進行四則運算
SZYS LABEL NEAR
CALL ISYSF ;首字元是運算子?
JZ SZYS2
CALL LOADATE ;不是,取數並儲存
MOV NUM1,AX
MOV NUM1+2,DX
SZYS1:
XOR AX,AX ;資料2清零
MOV NUM2,AX
MOV NUM2+2,AX
CALL ISYSF ;下個是運算子?
JZ SZYS3
JNZ SZYS6
SZYS2:
PUSH AX
MOV AX,JGV4 ;將結果作為資料1
MOV NUM1,AX
MOV AX,JGV4+2
MOV NUM1+2,AX
POP AX
SZYS3:
MOV YSF1,AL
MOV YSF2,AL
CALL ISJJ ;是加減運算轉
JZ SZYS4
CALL LOADATE ;取資料2
MOV NUM2,AX
MOV NUM2+2,DX
CALL JSII1 ;資料1與資料2根據YSF1進行乘除運算
JMP SZYS1 ; 結果儲存在資料1中
SZYS4:
CALL LOADATE ;取資料2並儲存
MOV NUM2,AX
MOV NUM2+2,DX
SZYS4_1:
CALL ISYSF
JNZ SZYS6
CALL ISJJ ;運算子2是加減運算?
JNZ SZYS5 ;不是轉
PUSH AX
CALL JSJJ ;資料1與資料2根據YSF1進行加減運算
POP AX ; 結果儲存在資料1中
MOV YSF1,AL ;儲存新的運算子
JMP SZYS4
SZYS5:
MOV YSF2,AL ;儲存運算子2
CALL LOADATE ;取資料3
MOV NUM3,AX
MOV NUM3+2,DX
CALL JSII2 ;資料2與資料3根據YSF2進行乘除運算
JMP SZYS4_1 ; 結果儲存在資料2中
SZYS6:
MOV CL,AL
CMP AL,13
JNZ SZYS9
SZYS7:
CALL JSJG
CMP JUV,0
JZ SZYS8
DEC JUV
POP YSF
POP NUM2+2
POP NUM2
POP NUM1+2
POP NUM1
RET
SZYS8:
CMP CL,')'
JZ SZYS10
MOV JGV4,AX
MOV JGV4+2,DX
JNZ SZYS12
SZYS9:
CMP AL,')'
JNZ SZYS11
INC SI
JMP SZYS7
SZYS10:
MOV NUM1,AX
MOV NUM1+2,DX
JMP SZYS1
SZYS11:
STC
RET
SZYS12:
CLC
RET
;數制處理
UVIL LABEL NEAR
PUSH SI
UVIL1:
LODSB
CMP AL,' '
JZ UVIL2
CMP AL,9
JZ UVIL2
CMP AL,13
JZ UVIL4
JNZ UVIL1
UVIL2:
MOV BX,SI
CALL OVERS
JZ UVIL3
LODSW
CALL OVERS
POP SI
JNZ SZYS11
CMP AX,'01'
JNZ SZYS11
PUSH SI
MOV UV,10
UVIL3:
MOV AL,13
MOV [BX-1],AL
UVIL4:
POP SI
CLC
RET
;預置結果
YVJG LABEL NEAR
MOV AH,52H
INT 21H
MOV AX,ES:[BX-2]
MOV DS,AX
MOV AX,DS:[0CH]
MOV CS:JGV4,AX
MOV AX,DS:[0EH]
MOV CS:JGV4+2,AX
PUSH CS
POP DS
PUSH CS
POP ES
RET
;儲存結果
BCJG LABEL NEAR
MOV AH,52H
INT 21H
MOV AX,ES:[BX-2]
MOV DS,AX
MOV AX,CS:JGV4
MOV DS:[0CH],AX
MOV AX,CS:JGV4+2
MOV DS:[0EH],AX
PUSH CS
POP DS
PUSH CS
POP ES
RET
STAR:
MOV SI,81H
CLD
CALL OVERS
JNZ STAR1
STAR0:
MOV DX,OFFSET MESS1
JMP STAR4
STAR1:
CALL YVJG
CALL UVIL
JB STAR0
MOV SAVESP,SP
CALL SZYS
MOV SP,SAVESP
MOV DX,OFFSET MESS2
JB STAR4
CALL CRLF
CALL XUJG
CALL BCJG
MOV DX,OFFSET MESS3
STAR4:
MOV AH,9
INT 21H
INT 20H
SAVESP DW 0
MESS1 DB 13,10,' Syntax:',13,10
DB ' JS
MESS2 DB 'Error in expression !$'
MESS3 DB 13,10,'$'
CODE ENDS
END NEWSTAR
點執行生成.exe檔案後放到了f盤裡,在dos環境下執行
f:>JS 3+2
5
f:>JS 6*7
2A
f:>JS 10-4
c
f:>JS 12/3
6