1. 程式人生 > >第5章 組合語言程式設計

第5章 組合語言程式設計

程式設計實現多位元組加法,如S=3B74AC60F8H+20D59E36C1H


DATA SEGMENT
  DATA1 DB 0F8H,60H,0ACH,74H,3BH
  DATA2 DB 0C1H,36H,9EH,0D5H,20H
DATA ENDS
CODE SEGMENT
  ASSUME CS:CODE,DS:DATA
  START:
        MOV AX,DATA
        MOV DS,AX
        MOV CX,5                 ;設定迴圈次數
        MOV SI,0                 ;置位移量初值
        CLC                      ;清進位CF
  LOOPER:
        MOV AL,DATA2[SI]         ;取一個加數
        ADC DATA1[SI],AL         ;和一個被加數相加,ADC dst,src  (dst)<-(dst)+(src)+(CF)
        INC SI                   ;位移量加1
        DEC CX                   ;迴圈次數減1
        JNZ LOOPER               ;不等於/非零轉移
        MOV AH,4CH
        INT 21H
CODE ENDS
  END START






計算三個位元組十六進位制數之和:3BH+74H+2CH=?

DATA SEGMENT
  BUF DB 3BH,74H,2CH
  SUM DB ?
DATA ENDS
CODE SEGMENT
  ASSUME CS:CODE,DS:DATA
  START:
        MOV AX,DATA
        MOV DS,AX
        MOV AL,BUF   ;取第一個數
        ADD AL,BUF+1 ;與第二個數相加
        ADD AL,BUF+2 ;與第三個數相加
        MOV SUM,AL   ;存和值
        MOV AH,4CH
        INT 21H
CODE ENDS
  END START


tab1為首地址存放了200個帶符號數,要求將各數求絕對值後存入以tab2為首地址的記憶體區。

DATA SEGMENT
  TAB1 DB 0E7H,0E4H,06H,11H,03H,01H
  TAB2 DB 6 DUP(?)
DATA ENDS
CODE SEGMENT
  ASSUME CS:CODE,DS:DATA
  START:
        MOV AX,DATA
        MOV DS,AX
        MOV CX,6
        MOV SI,0
  NEXT1:
        MOV AL,TAB1[SI]
        ;比較指令的執行結果將影響狀態標誌位。例如,若兩個被比較的內容相等,則(ZF)=1
        ;又如,假設被比較的兩個無符號數中,前者小於後者(即不夠減),則(CF)=1,等等。
        CMP AL,0
        ;JNS正轉移
        JNS NEXT
        ;NEG求補指令
        NEG AL
  NEXT:
        MOV TAB2[SI],AL
        INC SI
        DEC CX
        ;不等於,非零轉移
        JNZ NEXT1

        MOV AH,4CH
        INT 21H
CODE ENDS
  END START




在資料段從MYDATA開始的儲存單元中分別存放了兩個8位無符號數,試比較它們的大小,並將大者傳送到MAX單元。可程式設計如下:

DATA SEGMENT
  MYDATA DW 12,15
  MAX DW ?
DATA ENDS
CODE SEGMENT
  ASSUME CS:CODE,DS:DATA
  START:
        MOV AX,DATA
        MOV DS,AX
        LEA BX,MYDATA      ;將MYDATA的偏移地址送BX
        MOV AX,[BX]        ;第一個無符號數送AL
        INC BX             ;BX指向第二個無符號數
        CMP AX,[BX]        ;兩個數比較
        ;JNC disp8 (IP)<-(IP)+disp8 (CF)=0 不進位轉移
        JNC DONE           ;若CF=0,則轉DONE
        MOV AX,[BX]        ;否則,第二個無符號數送AL
  DONE:
        MOV MAX,AX
        MOV AH,4CH
        INT 21H
CODE ENDS
  END START



計算4609+3857=?

本例要求實現十進位制多位數的加法,假設被加數的每一位數都以ASCII碼形式存放在記憶體中,低位在前,高位在後。另外留出4個儲存單元,以便存放相加所得的結果。

DATA SEGMENT
  STRING1 DB 39H,30H,36H,34H
  STRING2 DB 35H,37H,38H,33H
  SUM DB ?,?,?,?
DATA ENDS
CODE SEGMENT
  ASSUME CS:CODE,DS:DATA
  START:
        MOV AX,DATA
        MOV DS,AX
        LEA SI,STRING1       ;(SI)<-被加數地址指標
        LEA BX,STRING2       ;(BX)<-加數地址指標
        LEA DI,SUM           ;(DI)<-結果地址指標
        MOV CX,4             ;(CX)<-迴圈次數
        CLC                  ;清進位標誌CF
  NEXT:
        MOV AL,[SI]          ;取一個位元組被加數
        ADC AL,[BX]          ;與加數相加 ADC dst,src  (dst)<-(dst)+(src)+(CF)
        AAA                  ;ASCII碼調整
        MOV [DI],AL          ;送存
        INC SI
        INC BX
        INC DI
        DEC CX
        JNZ NEXT             ;如不為零,轉NEXT
        MOV AH,4CH
        INT 21H
CODE ENDS
  END START




組合語言源程式的組織結構

組合語言源程式採用的是分段結構,即一個組合語言源程式由若干段組成(一般由資料段和程式碼段組成),每一個段以SEGMENT語句開始,以ENDS語句結束,整個程式的結尾是END語句。

在程式碼段中下面的內容是不可缺少的:

(1)  定義段(使用SEGMENT/ENDS語句定義)

(2)  約定段暫存器和段的關係(即物理段和邏輯段的關係,使用一個或多個ASSUME語句實現)

(3)  裝填段暫存器(只裝填資料型段暫存器)

(4)  設定返回DOS的方法

例如:
MYDARA   SEGMENT				; 定義資料段起始語句
        … …					; 定義資料
MYDATA   ENDS					; 定義資料段終止語句
MYCODE   SEGMENT				; 定義程式碼段起始語句
	ASSUME  CS:MYCODE,DS:MYDATA	; 約定段暫存器和段的關係
	START: 
		MOV  AX,MYDATA		; 裝填相應的段暫存器
		MOV  DS,AX			
                                   … …			; 完成所需功能的程式段
		MOV  AH,4CH			; 設定返回DOS
		INT    21H
MYCODE   ENDS				; 定義程式碼段終止語句
END   START					; 程式結束

組合語言語句的型別和格式

1.語句分類

① 指令性語句:也稱指令語句,指令系統的指令,彙編後產生目的碼。

② 指示性語句:也稱偽指令語句,告訴彙編程式如何彙編,彙編後不產生目的碼。

③巨集指令語句:自定義語句,由指令語句和偽指令語句組成的指令集合,不展開時不產生目的碼。

    2. 語句格式

組合語言是由一條條的語句組成的,其每條語句的格式如下:

[名字][語句字首]助記符[運算元][;註釋]

其中帶方括號的部分表示任選項,既可以有,也可以沒有。

(1)名字

名字是語句的符號地址,對於指令語句,名字稱為標號,其後必須加冒號;對於偽指令語句名字可以是變數名、段名、過程名等,其後不能加冒號:

eg:LOOPERMOV   AL, DATA2[SI]

DATA1   DB 0F8H, 60H,  0ACH, 74H, 3BH

DATA    SEGMENT

名字一般都有三個屬性:段屬性、偏移屬性和型別屬性

① 段屬性:表示名字所在段的起始地址(即段地址)。

② 偏移屬性:表示名字所在段的起始地址到定義該名字的地址之間的位元組數(即偏移量)。偏移量是一個16位無符號數。

③ 型別屬性:表示該名字的資料或地址的型別。

對於標號和過程名,型別屬性有NEARFAR兩種,表示只能在段內被引用還是可以在其它段被引用; •對於變數型別屬性有BYTE(位元組)WORD()DWORD(雙字)QWORD(四字)TBYTE(十位元組)等,表示資料區中存取操作物件的大小。 •對於段名只有段屬性,表示段的起始地址(段地址),而沒有偏移屬性和型別屬性。

(2)助記符

在指令語句中,表示該指令語句的操作碼,在偽指令語句中稱為定義符,它們指出其語句的功能。

(3) 運算元

運算元即為操作的物件。在指令語句中,可能有單運算元或雙運算元,也可能無運算元或隱含運算元;而在偽指令中可能有更多個運算元。當運算元不止一個時,相互之間應該用逗號隔開。

可以作為運算元的有:常數、暫存器、標號、變數和表示式等。

1)常量:是指令在中出現的哪些固定值,可以分為數值常數和字串常數兩類。

2) 暫存器:80868088CPU的暫存器可以作為指令的運算元。

3) 變數:是儲存器中某個資料區的名字,因此在指令中可以作為儲存器運算元。

4) 表示式:使用運算子把常數、暫存器、標號、變數等連線起來的運算式。

① 表示式分為數值表示式和地址表示式兩種。

② 表示式中常用的運算子有以下幾種:

算術運算子:+、-、*、/和MOD(模除,即兩個整數相除後取餘數)等。

邏輯運算子:ANDORXORNOT等。

關係運算符:EQNELTGTLEGE等。

分析運算子:SEGOFFSETTYPESIZE

LENGTH等。

合成運算子:PTRTHISSHORT等。

其它運算子: :、LOWHIGH

(4)註釋

註釋是對彙編語句的功能或彙編程式的說明。

mov ax, 4eq3   ;4eq3為假,(ax)<-0000h
mov ax, 4ne3   ;4ne3為真,(ax)<-0ffffh

mov ax, data
mov ax, seg data

type, length, size

組合語言源程式的上機過程

上機環境


上機過程


(1) 編輯程式

DOS環境下用EDIT編輯器

WINDOWS環境下用記事本

(2)彙編源程式

巨集彙編程式 MASM.EXE 或小彙編程式ASM.EXE

彙編程式主要有以下功能:

① 檢查源程式中語法錯誤,給出錯誤提示資訊

② 產生目標檔案(.OBJ)、列表檔案(.LST)及交叉引用檔案(.CRF

③ 展開巨集指令

MASM巨集彙編的提示資訊及回答


(3) 連線目標檔案

通過 LINK.EXE 程式實現

① 將多模組連線,產生一個.EXE檔案

② 連線庫檔案(.LIB)及產生連線映象檔案(.MAP

LINK的提示資訊及回答


(4) 執行程式

當我們建立了可執行檔案後,就可以直接在DOS下執行該程式。

程式除錯

DEBUG是一種面向組合語言的動態除錯工具,共有19條命令。DEBUG提供了可以跟蹤、測試程式的環境和條件,使編輯者能夠對.EXE.COM檔案的執行進行動態跟蹤除錯,能夠較快地查找出檔案的錯誤和檢查程式的執行結果。

還可以利用DEBUG直接編寫一段小的彙編程式,並進行除錯和執行。

DEBUG 常用命令

A[ 起始地址]↙  彙編並儲存一段指令語句

U[ 起始地址]↙  反彙編

T[=起始地址]↙  單步執行(執行一條語句)

R[ 暫存器]↙    顯示或修改暫存器內容

D[儲存單元邏輯地址]↙  顯示儲存單元

80個位元組/次)

N[檔名]↙     定義檔案

L↙              裝入檔案

例如:

DATA  SEGMENT
        NUM  DB  82H,68H,88H
        SUM  DB  ?
DATA  ENDS
CODE  SEGMENT
        ASSUME  CS:CODE,DS:DATA
        START:	MOV   AX,DATA
			MOV   DS,AX
			MOV   BX,OFFSET  NUM
			MOV   AL,[BX]
			INC     BX
			ADD    AL,[BX]
			INC     BX
			ADD    AL,[BX]
			MOV   SUM,AL
			MOV   AH,4CH
			INT     21H
CODE  ENDS
	  END   START

新增堆疊段
stack segment stack stack
	buf db 20 dup(?)
stack ends

5.3 偽指令語句

巨集彙編程式MASM提供了約幾十種偽指令,其中有一些偽指令小彙編ASM不支援,例如巨集處理偽指令等。根據偽指令的功能,大致可以分為以下幾類:

⒈方式偽指令

.8086。彙編程式將在80868088方式下操作。

.386。彙編程式將在80386方式下操作。

3.資料定義偽指令

資料定義偽指令的一般格式為:

[變數名] 偽操作符 運算元[,運算元]

⑴ DB 定義變數的型別為BYTE,給變數分配位元組或位元組串運算元。

DW 定義變數的型別為WORD,給變數分配字運算元。

DD 定義變數的型別為DWORD,給變數分配雙字運算元。

除了常數、表示式和字串外,問號也可以作為資料定義偽指令的運算元,此時僅給變數保留相應的儲存單元,而不賦與變數某個確定的初值。

當同樣的運算元重複多次時,可用重複操作符DUP表示,其形式為:

n DUP(初值[,初值])

可以巢狀使用:

ARR DB 100 DUP(3 DUP(8), 6)

: 畫圖說明下列偽指令所定義的資料在記憶體中的存放形式。

ARV1  DB 3+4,43H,-2
ARV2  DW 474FH,1,?
COUNT  EQU  2
ARV3  DB  2DUP(1,COUNT DUP(2))
ARV4  DD ARV3
ARV5  DB ‘AB’
ARV6  DW ‘AB’
解:假設此資料段的段地址為1234H,即 DS1234H,則有:
DATA DB 101,0F0H     ;存入65H,F0H
EXPR DB 2*8+7          ;存入17H
STR   DB 'WELCOME'   ;存入8個字元的ASCII碼值
AB     DB 'AB'               ;存入41H、42H
BA     DW 'AB'              ;存入42H、41H
ABDD  DD 'AB'              ;存入42H、41H,00、00
OFFAB  DW  AB            ;存入變數AB的偏移地址
ADRS   DW STR,STR+3,STR+5     ;存入3個偏移地址
TOTAL  DD  DATA         ;先存DATA的偏移地址,再存段地址


下面列出幾個錯誤的資料定義偽指令語句。

ERROR1: DW 99 ;變數名後有冒號

ERROR2: DB 25*90  ;位元組型變數的運算元超過255

ERROR3:  DD '1234'   ;超過2個字元的字串變數只能用DB定義

2. 符號定義偽指令

EQU(賦值偽指令)

名字 EQU 表示式

⑵=(等號偽指令)

名字=表示式

LABEL(型別定義偽指令)

名字 LABEL 型別

注意:

EQU=類似,但EQU不能對同一符號重複定義。

count = 100

mov cx, count

……

count = count – 20

mov bx, count

4.段定義偽指令

段定義偽指令的用途是在組合語言源程式中定義邏輯段,常用的段定義偽指令有SEGMENTENDSASSUME

SEGMENTENDS 偽指令

段名 SEGMENT [定位型別][組合型別][類名]

段名 ENDS

定位型別。定位型別給出實際段起點的型別。它有PAGE(頁型別)、PARA(節型別)、WORD(字型別)、BYTE(位元組型別)四種類型。其中PARA為預設值。

例:
DATA  SEGMENT
        NUM  DB  82H,68H,88H
        SUM  DB  ?
DATA  ENDS
STACK SEGMENT STACK STACK
        BUF DB 20 DUP(?)
STACK ENDS
CODE  SEGMENT BYTE
        ASSUME  CS:CODE,DS:DATA
        START:	MOV   AX,DATA
			MOV   DS,AX
               ……

			MOV   AH,4CH
			INT     21H
CODE  ENDS
	  END   START

BYTE:   從位元組開始

WORD:從字邊界開始

PARA,從節邊界開始, 1=16B

PAGE:  從頁邊界開始, 1=256B

組合型別。組合型別在多模組程式設計中表示該段和其它同名段間的組合連線方法。組合型別有PUBLICCOMMONATMEMORYSTACK等。

③類名。類名是程式設計師任選的一個字串,使用時必須用單引號括起來。其作用是在連線時決定各邏輯段的裝入順序。

ASSUME偽指令

它是用來說明邏輯段和物理段關係的偽指令,即告訴彙編程式在指令執行期間記憶體的哪一段是資料段,哪一段是堆疊段,哪一段是程式碼段。

ASSUME 段暫存器名:段名[,段暫存器名:段名,]

5.過程定義偽指令

過程名  PROCNEAR/FAR

……

RET

……

過程名  ENDP

注意:

1.一定有RET語句,可能不止一條 2.過程的定義可以巢狀 3.NEAR只能被本段呼叫,FAR可以被其他段呼叫

6.模組定義與連線偽指令

END [標號]

表示源程式到此結束,指示彙編程式停止彙編。

PUBLIC

說明本模組中某些符號是公共的,能被其他模組訪問

EXTRN

說明本模組中某些符號是外部的,由別的模組中定義的,定義時需加PUBLIC

5.2組合語言和DOS作業系統的介面

1.使用者程式在儲存器中的位置

2.使用者程式的裝入

完成以下操作:

¬確定記憶體可用部分

以便存放要執行的 .exe 檔案。

­建立程式段字首 PSP

Program  Segment Prefix

◢  程式段字首大小100H

256個位元組。

存放執行過程中的控制資訊。

PSP最開始的兩個位元組CD20

是一條 INT20H指令。

®裝入可執行程式.exe
DSEG  SEGMENT
        STRING1  DB  1,2,3,4,5
DSEG  ENDS
ESEG  SEGMENT
        STRING2  DB  ?
ESEG  ENDS
SSEG  SEGMENT  STACK  ‘STACK’
                  DW  10  DUP(?)
SSEG  ENDS
CSEG  SEGMENT
        ASSUME  CS:CSEG,DS:DSEG
        ASSUME  ES:ESEG,SS:SSEG
        START: MOV   AX,DSEG
	       MOV   DS,AX
               MOV   AX,ESEG
	       MOV   ES,AX
	
               LEA  SI,STRING1
               LEA  DI,STRING2
               MOV  CX,5
               CLD
               REP  MOVSB
	       MOV   AH,4CH
	       INT     21H
CSEG  ENDS
END   START

3.返回DOS的方法

執行使用者程式後,若要返回 DOS狀態,即在螢幕上出現DOS提示符,等待輸入新的命令,應在使用者程式的最後安排完成此功能的程式段。

為了保證使用者程式執行完後,能回到DOS,可使用如下兩種方法:

(1)非標準方法:呼叫INT21H4CH功能,例如:

  MOV  AH4CH

  INT  21H

(2) 標準方法:借用PSP首單元的INT20H返回DOS

這種方法較麻煩。由於執行INT 20H的前提是CS:IP必須指向PSP首單元,否則執行INT20H反而會造成宕機,因此在.EXE檔案彙編格式中,不能直接執行INT20H。用下列方法可使在需返回DOS時,CS:IP指向PSP首單元。

① 把主程式定義成一個遠過程。即:

過程名  PROC FAR

   RET

過程名  ENDP   

在給DSES賦初值之前,用下列三條指令,把PSP首單元的邏輯地址壓入堆疊,即

  PUSH  DS  PSP段地址壓棧

  MOV   AX0;或用XORAX,AX指令

  PUSH  AX  PSP段首單元的偏移地址

;壓棧(偏移地址為0000H)

採取了以上措施之後,程式在返回DOS的時候,執行一條RET指令即可返回DOS。因為這條RET指令是遠過程中的RET指令,它將從棧頂彈出四個位元組,即把PSP首單元的邏輯地址反彈到CS:IP之中,於是CPU就自動從PSP首單元取出INT20H,執行它返回DOS

例如:
DATA  SEGMENT
        NUM  DB  82H,68H,88H
        SUM  DB  ?
DATA  ENDS
CODE  SEGMENT
        MAIN  PROC  FAR
        ASSUME  CS:CODE,DS:DATA
        START:  PUSH  DS
                XOR   AX,AX
                PUSH  AX	
                MOV   AX,DATA
                MOV   DS,AX
	        LEA    BX, NUM
	        MOV   AL,[BX]
		INC     BX
		ADD    AL,[BX]
		INC     BX
		ADD    AL,[BX]
		MOV   SUM,AL                             
                     RET
         MAIN   ENDP
CODE  ENDS
             END   START

4.資料的輸入與輸出(DOS功能呼叫)

微型計算機系統為彙編使用者提供了兩個程式介面來使用計算機的硬體資源,一個是DOS功能呼叫,另一個是ROM中的BIOS(basicinput/output system) 功能呼叫。DOS功能呼叫和BIOS功能呼叫都是由一系列的服務子程式構成的,但呼叫與返回不是使用子程式呼叫指令CALL和返回指令RET,而是通過軟中斷指令INT n和中斷返回指令IRET呼叫和返回的。

軟中斷(INTn指令)可分為三部分:

① ROM BIOS中斷,佔用型別號為10H~1FH

DOS中斷,佔用型別號為20H~3FH。目前使用的有20H~27H2FH,其餘型別號保留。

③ 自由中斷,佔用型別號為40H~FFH,可供系統或應用程式設定開發的中斷處理程式用。

1DOS中斷及功能呼叫

目前DOS常用的9類中斷(20H~27H2FH)分為兩種:

DOS專用中斷:INT22HINT23HINT24H,使用者不能使用。

DOS可呼叫中斷:INT20HINT27H(程式退出)INT25HINT26H(磁碟RW中斷)INT2FH(假離線列印檔案)INT21H(系統功能呼叫)

2BIOS中斷呼叫

BIOS中斷功能依功能分為兩種,一種為系統服務程式,另一種為裝置驅動程式。其中中斷型別號為10H16H17H的是顯示器、鍵盤和印表機的驅動子程式。

①鍵盤輸入子程式:INT16H

  ②顯示輸出子程式:INT10H

③列印輸出子程式:INT17H

3)DOSBIOS功能呼叫方法

對於所有的功能呼叫,使用時一般需要經過以下三個步驟:

① 子程式入口引數送相應暫存器。

②子程式編號(功能號)AH暫存器:

MOV AH,功能號。

③發中斷請求:

INT n

(系統功能呼叫使用INT 21H指令)。

4)系統功能呼叫

系統功能呼叫是指INT21H中斷。它是可供系統程式和應用程式呼叫的一個極其重要的中斷,內含近百個已經標準化了的系統呼叫子功能。它是構成作業系統核心的主要成分。

這裡我們主要介紹他的幾個成用的功能。如下表所示。


INT21H 常用功能介紹

1)鍵盤輸入(1#功能)

功能: 鍵盤輸入一個字元,將其ASCII碼存放於AL,並在螢幕上顯示該字元

輸入字元ASCII®AL

MOV AH,01H

INT 21H

2)字元顯示(2#功能)

功能:在螢幕上顯示任意單個字元

待輸出字元ASCII®DL  

MOV  DL,A

MOV AH,2

INT 21H

3)字串顯示(9#  功能)

功能:螢幕上顯示一串以$結尾的字元

待顯示字串首單元地址®DSDX

DATA  SEGMENT

BUF  DB  HOW DO YOU DO?$

DATA  ENDS

  CODE  SEGMENT

        MOV DX,OFFSET BUF

        MOV AH,9

        INT 21H

CODE  ENDS

4)字串輸入(10#功能)

功能: 鍵盤輸入一串字元存至儲存區

儲存區起始單元地址(段地址:偏移量)®(DS:DX)      儲存區特點:

首位元組為儲存區最大長度M1~255);

第二位元組存放輸入字串的實際長度

第三位元組以後為使用者輸入內容(含結束標識回車的ASCII0DH

例   從鍵盤輸入一串字元,個數小於50
     其程式設計方法是:
	DATA   SEGMENT
	      BUF  DB  50
		   DB  ?
		   DB  50  DUP(?)
	DATA	  ENDS
	CODE	  SEGMENT           
	ASSUME CS:CODE, DS:DATA
	START:……
		LEA   DX, BUF
		  MOV   AH,  10
		  INT   21H
                                 ……
            CODE  ENDS
		END START



5.4 巨集指令及其使用

1.巨集指令、巨集定義和巨集呼叫

巨集指令是源程式中具有獨立功能的一段程式程式碼。在組合語言中,如果在源程式中需要多次使用同一個程式段,可以將這個程式段定義(巨集定義)為一個巨集指令,然後每次需要的時候,即可簡單地用巨集指令名來代替(稱為巨集呼叫),從而避免了重複書寫,使源程式更加簡潔、易讀。

巨集定義由MASM巨集彙編程式提供的偽指令實現。

1. 巨集定義

巨集指令名 MACRO[形式引數]

ENDM

2. 巨集呼叫

巨集指令名 [實際引數]

這就是說,只要在源程式中寫上已定義過的巨集指令名就算是呼叫該巨集指令了。

3. 巨集展開

具有巨集呼叫的源程式被彙編時,每個巨集呼叫將被MASM進行巨集展開。

巨集展開實際上是用巨集定義時設計的巨集體去代替相應的巨集指令,並用實際引數一一取代形式引數。

由此可見,使用巨集的過程共有三步:首先進行巨集定義;然後可以進行巨集呼叫;最後,彙編時由MASM進行巨集展開。

[] 若源程式中多處需要將ALCL暫存器中的兩位壓縮型的BCD數相加,並將和送回CL暫存器,則可象下述這樣定義巨集指令,然後在需要的地方進行呼叫。

DECADD  MACRO

ADD AL,CL

DAA

MOV CL,AL

ENDM

顯而易見,這是一個無形式引數的巨集定義。

如果對分別存放在任意8位暫存器或儲存單元中的兩個壓縮型的BCD數進行加法運算,則可將上例巨集定義改寫為

DECADD1 MACRO OPR1,OPR2

MOV AL,OPR1

ADD AL,OPR2

DAA

MOV OPR1,AL

ENDM

例如有以下巨集呼叫,如何展開呢?

DECADD1  DL, BUFFER

DECADD1  AREA1, AREA2

則彙編時進行巨集展開,得到以下指令:

DECADD1  DL, BUFFER

+ MOV  AL, DL

+ ADD  AL, BUFFER

+ DAA

+ MOV  DL, AL

DECADD1  AREA1, AREA2

+ MOV  AL, AREA1

+ ADD  AL, AREA2

+ DAA

+ MOV  AREA1, AL

2.巨集指令與子程式(過程)

在組合語言程式設計中,巨集指令和子程式都給設計者提供了很大方便。他們都是可被程式多次呼叫的程式段,並且呼叫前必須由設計者根據需要按一定格式進行定義。然而,巨集指令和子程式由於定義方法和其格式不同,因此,

相關推薦

5 組合語言程式設計

程式設計實現多位元組加法,如S=3B74AC60F8H+20D59E36C1H DATA SEGMENT DATA1 DB 0F8H,60H,0ACH,74H,3BH DATA2 DB 0

組合語言5迴圈程式設計

迴圈結構 控制方法分 1.計數型迴圈結構 2.條件型迴圈結構 按照結構可分為單迴圈和多迴圈 指令 loop:用於單條件判斷。 loopnz/loope:用於多條件判斷。 程式就像人的思維方式,都是有判斷條件組成的。所以說沒有編寫

Java程式設計思想學習(五)----5:初始化與清理

隨著計算機革命的發展,“不安全”的程式設計方式已逐漸成為程式設計代價高昂的主因之一。 C++引入了構造囂(constructor)的概念,這是一個在建立物件時被自動呼叫的特殊方法。Java中也採用了構造器,並額外提供了“垃圾回收器”。對於不再使用的記憶體資源,垃圾回收器能自動將其釋放。 5.1 用構造器確

《Java多執行緒程式設計實戰》——5 Two-phase Termination(兩階段終止)模式

Two-phase Termination模式通過將停止執行緒分解為準備階段和執行階段兩個階段,提供了一種通用的優雅停止執行緒的方法。 準備階段:通知目標執行緒準備進行停止。 設定標誌變數。 呼叫目標執行緒的interrupt方法。 對於能夠對interrupt方法呼

《TCP/IP網路程式設計5 筆記&程式碼&註釋

在第四章中的回聲迭代客戶端中,客戶端通過write()一次性將字串傳送過去,之後呼叫read()等待接受自己傳輸的字串,因此這個回聲迭代客戶端是不完美的。 解決方法就是提前確定接受資料的大小: //Linux while(1) { //......相同省略 int str_l

《Lua程式設計(4版)》:5練習答案

練習5.1 monday sunday sunday 練習5.2 一樣,都指向該表。 a.a.a.a=3,執行的是該表的索引 a 賦值為3,之後的a.a.a.a將會引發異常,因現a.a=3,而非

C++ primer 程式設計練習題 5

Practice makes Pefect.! #include<iostream> #include<string> /*string I/O*/ using namespace std; struct Car { stri

Java程式設計(Java9版):5 類與物件

jshell> class Point{ ...> private double x; ...> private double y; ..

Visual C++網路程式設計經典案例詳解 5 網頁瀏覽器 製作個性化介面 工具欄程式設計 新增工具欄按鈕

製作網頁瀏覽器時 使用者還需要新增一些功能。 例如 使用者重新整理上一步下一步 和瀏覽記錄等。 這些操作在VC中實現非常簡單。 首先在資源管理器中,展開Toolbar項 新增四個工具欄按鈕 按鈕的ID分別為 ID_VIEWRECORD、ID_PRE、ID_NEXT、ID_REFR

Visual C++網路程式設計經典案例詳解 5 網頁瀏覽器 製作個性化介面 工具欄程式設計 OnCreate()函式

在這裡 使用者需要用到MFC中CReBar類 該類相當於一個容器 可以將多個控制元件組合在一起 程式碼如下 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { ...//省略部分程式碼 if(dlg.m_hWnd==NU

Visual C++網路程式設計經典案例詳解 5 網頁瀏覽器 製作個性化介面 工具欄程式設計 新增對話方塊到工具欄

將ID為ID_DIALOG 的對話方塊新增到工具欄中, 使用者需要將類物件設定為CMainFrame類的成員變數 首先,在CMainFrame類的標頭檔案"MainFrm.h"開頭處 新增CTooldlg類的標頭檔案“Tooldlg.h” ... //省略部分程式碼 #includ

Visual C++網路程式設計經典案例詳解 5 網頁瀏覽器 製作個性化介面 工具欄程式設計 介面設計

在工程中新增一個對話方塊作為位址列等控制元件的面板 ID為 ID_DILOG 將組合框與連線按鈕放置到對話方塊面板上 介面中的各個控制元件以及屬性如表所示 控制元件ID及其屬性 控制元件ID IDC_STATIC IDC_COMBO1 IDC_BUTTON1 屬性 地址 地址輸入框

Visual C++網路程式設計經典案例詳解 5 網頁瀏覽器 製作個性化介面 工具欄程式設計

在VC中製作與IE功能相似的網頁瀏覽器 可以使用MFC中的CHtmlView類 也可以使用ActiveX控制元件類CWebBrowser2實現網頁瀏覽器的開發 對於網路瀏覽器而言 工具欄是很重要的一部分 在工程中使用工具欄可以方便使用者的操作。 使用者通過工具欄上的位址列輸入網頁地址

Visual C++網路程式設計經典案例詳解 5 網頁瀏覽器 HTTP響應 實體資料 類獲取響應訊息的響應碼

結構體的用法很簡單。 例如,利用該類獲取響應訊息的響應碼 程式碼如下 ... message msg; //結構體物件 CString str; //存放響應碼 msg.messagehead=&recvdata; //recvdata 為接收到的響應訊息

Visual C++網路程式設計經典案例詳解 5 網頁瀏覽器 HTTP響應 實體資料 自定義一個簡單的訊息體結構

總之,伺服器返回的響應訊息類似於C++語言中的結構體 訊息頭和訊息體就是這個結構體裡面的元素。 使用者在使用HTTP程式設計時, 可以根據需要自定義一個結構體儲存該訊息資料。 例如,自定義一個簡單的訊息結構體 typedef struct { char *messagehead; /

Visual C++網路程式設計經典案例詳解 5 網頁瀏覽器 HTTP響應 實體資料 伺服器的訊息響應格式

在伺服器的響應訊息中包括了訊息頭和訊息體兩部分。 其中訊息體中包含的實體資料。 並且在訊息頭和實體資料之間使用一個空白行進行分隔。 例如 客戶端向伺服器請求一個頁面GET.html 伺服器的響應訊息格式如下 HTTP/1.1 200 OK//訊息頭。 Date: Mon,21 Nov

Visual C++網路程式設計經典案例詳解 5 網頁瀏覽器 HTTP響應 實體標題欄位資訊 Content-Length標題

該標題必須與Content-type標題一起使用 用於表示實體資料的大小(以位元組為單位) 其用法如下 HTTP/1.1 200 OK Date: Mon,21 Nov 2008 18:33:22 GMT Sever: Microsoft-IIS/6.0 Accept-Ranges: b

Visual C++網路程式設計經典案例詳解 5 網頁瀏覽器 HTTP響應 實體標題欄位資訊 Content-type標題

在伺服器的響應訊息中含有實體資料 Content-type標題可以用於指示實體資料的個數 以及所使用的字符集 Content-type:text/html; charset=ASCII 實體資料是文字格式的HTML檔案 所使用的字符集為XLM 如果伺服器返回一幅 XLM 或其他格式

Visual C++網路程式設計經典案例詳解 5 網頁瀏覽器 HTTP響應 響應狀態資訊 響應標題欄位資訊 Location標題

在響應標題欄位資訊中包含了伺服器返回除響應行以外的其他資訊 當伺服器上的資源被儲存到其他地址以後 伺服器會將新地址到客戶端 這時在響應標題欄位中會新增Location標題 該標題表示資源的實際位置 並且使絕對的URL地址 HTTP/1.1 302 OK Date: Mon,21 No

Visual C++網路程式設計經典案例詳解 5 網頁瀏覽器 HTTP響應 響應狀態資訊 響應碼一些具體含義

如果使用者需要了解響碼具體情況, 請參考RFC2068 其中給出了具體響應碼的含義。 例如,響應碼的一些具體含義。 響應碼 意義 201 伺服器建立了一個新資源