?? 匯006.txt
字號:
Flat
NEAR NEAR 16-bit Yes
NEAR NEAR 16-bit No
NEAR FAR 16-bit No
FAR NEAR 16-bit No
FAR FAR 16-bit No
FAR FAR 16-bit No
NEAR NEAR 32-bit Yes
、SMALL
所有的數據變量必須在一個數據段之內,所有的代碼也必須在一個代碼段之內。在這種模型下,數據段寄存器的內容保持不變,所有轉移也都是段內轉移。
該存儲類型是獨立匯編語言源程序常用的存儲模型。
、MEDIUM
所有的數據變量必須在一個數據段之內,但代碼段可以有多個。在這種模型下,數據段寄存器的內容保持不變,轉移可以是段間轉移。
、COMPACT
數據段可以有多個,但代碼段只能有一。
、LARGE
數據段和代碼段都可以有多個,但一個數組的字節數不能超過64KB。
、HUGE
數據段和代碼段都可以有多個,一個數組的字節數也可以超過64KB。
、FLAT
FLAT存儲模式在創建執行文件時,將使該程序僅含一個包括程序數據和代碼的32位段,并且只能在80386及其以后的計算機系統中運行。該程序的文件類型為EXE。
在使用該存儲模式之前,必須先用偽指令.386、.486或其它偽指令來說明更高性能的CPU類型。也就是說:FLAT模式僅在386及其以后CPU模式下才能使用。
在該程序中,所有代碼和數據位距的缺省值都是NEAR,子程序的類型也是NEAR,并且標識符@CodeSize,@DataSize和@Model的值分別為:0、0和7。
在FLAT存儲模式下,程序將不使用段寄存器FS和GS。匯編程序在處理說明語句“.MODEL FLAT”時,將自動生成下列段寄存器說明語句:
ASSUME CS:FLAT, DS:FLAT, SS:FLAT, ES:FLAT, FS:ERROR, GS:ERROR
當然,程序員也可把該段寄存器說明語句寫在其指令序列之中。
二、語言類型
其詳細說明請見7.5.3節中所述。
三、操作系統類型
OS_DOS是當前唯一支持的選項值,也是該選項的缺省值。
四、堆棧類型
堆棧類型的值主要影響偽指令.STARTUP所生成的指令序列。該選項有二個可選值:NEARSTACK和FARSTACK。其中:NEARSTACK是該選項的缺省堆棧類型。
、NEARSTACK——堆棧段和數據段是同一段;
、FARSTACK——堆棧段和數據段是不同的段,且堆棧不在段組DGROUP中。
例如:
.MODEL SMALL, C, OS_DOS, FARSTACK
6.4.2 簡化段定義偽指令
簡化段定義偽指令在說明一個新段即將開始的同時,也說明了上一個段的結束。在本段定義結束時,也不必用偽指令“ENDS”來標識。
具體的偽指令說明形式及其功能描述如下:
1、代碼段定義
.CODE
作用:說明其下面的內容是代碼段中內容。
2、堆棧段定義
.STACK [堆棧字節數]
其中,“堆棧字節數”可以不寫,其缺省值為1024B。
3、數據段定義
.DATA / .DATA? / .CONST
作用:說明其下面的內容是數據段中的變量定義。
在一個源程序中,可以有多個偽指令.DATA定義的數據段,這就好象在源程序中定義多個同段名的數據段一樣。
偽指令.DATA?說明下面是一個未初始化數據段的開始,偽指令.CONST說明下面是一個常數數據段的開始。這二條偽指令很少使用,除非在與高級語言編寫的程序相結合時,為了遵守高級語言的某些約定,而需要特殊說明時才使用。
匯編程序在處理簡化的堆棧段和數據段定義時,它會自動地把偽指令.STACK、.DATA、.DATA?和.CONST所定義的段組合成一個段組。如果想定義一個獨立的、不與其它段組合在一起的數據段的話,那么,就可選用下面的數據段定義方式。
4、遠程數據段定義
.FARDATA [段名] / .FARDATA? [段名]
其中:“段名”是可選項,如果不指定的話,則該段名就取其缺省段名。
作用:說明一個獨立的數據段。
偽指令.FARDATA?說明下面是一個未初始化的、獨立數據段的開始。通常情況下,很少使用該偽指令。
6.4.3 簡化段段名的引用
當使用簡化的段定義時,一般情況下,程序員可以不知道這些段的段名、段地址堆齊類型和組合類型等。但當把簡化定義的段和標準定義的段混合使用時,就需要知道簡化定義段的基本屬性。表6.3是在小模式下段的基本屬性對應表。
表6.3 小模式下簡化段定義的缺省屬性表
偽指令
缺省段名
對齊類型
組合類型
類別
段組名
.CODE
_TEXT
WORD
PUBLIC
'CODE'
.FARDATA
FAR_DATA
PARA
NONE
'FAR_DATA'
.FARDATA?
FAR_BSS
PARA
NONE
'FAR_BSS'
.STACK
STACK
PARA
STACK
'STACK'
DGROUP
.DATA
DATA
WORD
PUBLIC
'DATA'
DGROUP
.DATA?
BSS
WORD
PUBLIC
'BSS'
DGROUP
.CONST
CONST
WORD
PUBLIC
'CONST'
DGROUP
在其它存儲模型下,由偽指令".CODE"說明的代碼段段名在"_TEXT"之前還要加上其模塊名(源程序名)。假設,某模塊名為ABC,則其缺省的代碼段段名就為ABC_TEXT。因此,在這種情況下,程序的模塊名或源程序名不要以數字開頭。
例6.15 簡化段定義的方法
.MODEL SMALL
.STACK 128
.DATA
MSG DB "Simplified Segment Directives.$"
.CODE
MOV AX, @DATA ;取數據段的段值
MOV DS, AX ;把給段寄存器DS賦值
MOV DX, offset MSG
MOV AH, 9H
INT 21h
MOV AX, 4C00H
INT 21h
END
另外,在匯編程序MASM中,還提供了二組簡化的代碼偽指令:.STARTUP和.EXIT。
、.STARTUP——在代碼段的開始,用于自動初始化寄存器DS、SS和SP;
、.EXIT——用于結束程序的運行,它等價于下列二條語句:
MOV AH, 4CH
INT 21h
當使用匯編程序TASM時,以上二條偽指令分別改為:STARTUPCODE和EXITCODE。假設使用匯編程序MASM,那么,例6.15可改寫成例6.16的形式。
例6.16
.MODEL SMALL
.STACK 128
.DATA
MSG DB "Simplified Segment Directives.$"
.CODE
.STARTUP ;自動初始化寄存器DS、SS和SP
MOV DX, offset MSG
MOV AH, 9H
INT 21h
.EXIT
END
6.5 源程序的輔助說明偽指令
除了以上一些使用率較高的偽指令外,還有一些使用頻率不太高的其它偽指令。下面僅列舉幾個這樣的偽指令。
6.5.1 模塊名定義偽指令NAME
模塊名定義偽指令NAME說明該源程序的模塊名。該偽指令的一般格式如下:
NAME [模塊名字符串]
6.5.2 頁面定義偽指令PAGE
在源程序的開始,可用偽指令PAGE說明每頁的最大行數、每行的字符數。該偽指令的一般格式為:
PAGE [[行數], 寬度]
其中:“行數”的取值范圍為[10, 255],“寬度”的取值范圍為[60, 132]。
如:偽指令“PAGE 60, 80”說明每頁最多有60行,每行最多有80個字符。
如果要在某指定行之后強行換頁的話,那么,可在該行的下面書寫不帶操作數的偽指令PAGE。
6.5.3 標題定義偽指令TITLE
標題定義偽指令TITLE說明打印的標題,該標題可有60個字符。該偽指令在源程序頭部只能書寫一次,其一般格式如下:
TITLE [標題字符串]
如果程序中沒有使用NAME偽操作,則匯編程序將用“標題字符串”的前六個字符串作為其模塊名。如果程序中既無NAME偽操作,也無TITLE偽指令,那么,源文件名將作為模塊名。
在匯編程序TASM環境下,標題定義偽指令是%TITLE。
6.5.4 子標題定義偽指令SUBTTL/SUBTITLE
子標題定義偽指令SUBTTL/SUBITLE說明打印頁上的子標題,該子標題也可有60個字符,它在每頁的第三行打印。該偽指令的一般格式如下:
SUBTTL/SUBTITLE [標題字符串]
6.6 習題
6.1、簡述ASSUME偽指令的作用,用該語句說明的段寄存器不用對其賦段地址的初值?
6.2、用二種定義方法堆棧段,并給出相應的初始化語句或說明。
6.3、把下列C語句的語句改寫成功能相同的匯編語言程序片段(其中:變量都為整型變量)。
1)、h = (key & 0XFF00) >> 8;
2)、k = (k + '1' – 0xabcd) / 56;
3)、for (i = s = 0; i < 100; i++) s += data[i] * 2;
4)、for (s = 0, i = 100; i > 0; i--) s += i * 2;
6.4、把下列C語言的語句改寫成等價的匯編語言程序段(不考慮運算過程中的溢出)。
If (a<1 || b/4 > 10 && c%8==5) {
a = 20+b++;
c <<= 2;
}
else {a = 21-(++c);
b--;
}
其中:變量a、b和c都是有符號的整型(int)變量。
6.5、假設內存單元中有三個字a、b和c,編寫一個程序,它可判斷它們能否構成一個三角形,若能,CF為1,否則,CF為0。
6.6、假設有三個無符號字存放在以Buffer為開始的緩沖區中,編寫一個程序把它們從低到高排序好。
6.7、編寫一個程序,它把一位十六進制數轉化成相應的數字字符或大寫字母。
6.8、編寫一個程序,它把一個合法的十六字符轉化成相應的數值。
6.9、編寫一個程序,它可統計32數DX:AX中二進制位是1的位數。
6.10、編寫一個程序,它把CH和CL中的二進制位依次交叉存入AX中。
6.11、編寫一個程序,求出從內存單元1000:0000開始的1024個字的32位累加和,并把該值存入程序中的變量Data中。
6.12、假設從變量Buff開始存放了200個字,編寫一個程序統計出其正數、0和負數的個數,并把它們分別存入N1、N2和N3中。
6.13、用雙重循環把下三角乘法表存入從product開始的45個字節中。
6.14、表示源程序結束的偽指令是什么?在其后所編寫的指令在被匯編嗎?
6.15、匯編語言程序一定會從代碼段的第一條指令開始執行嗎?如果不是,如何指定程序的入口地址?
6.16、編寫一個程序,它把字符串String兩端的空格刪除(字符串以0結束)。
6.17、編寫一個程序,它把字符串String中的數字字符刪除掉(字符串以0結束)。
6.18、編寫一個程序,它把AX的值以二進制字符串的形式存放在以buff開始的緩沖區中。
6.19、假設有一個以Data為首地址的字緩沖區,其緩沖區的大小在第一個字中,試編寫一個程序,求出該緩沖區數值的最大值和最小值,并分別存入DI和SI中。
6.20、編寫一個程序片段,把32位數DX:AX向左移六位。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -