2022-12-10

以簡化的方式進(jìn)行編譯和鏈接

1.exe的執(zhí)行

程序運(yùn)行,只是從屏幕上不可能看到任何運(yùn)行結(jié)果,因?yàn)?,我們的程序根本沒有向顯示器輸出任何信息。程序只是做了一些將數(shù)據(jù)送入寄存器和加法的操作,而這些事情,我們不可能從顯示屏上看出來。程序執(zhí)行完成后,返回,屏幕上再次出現(xiàn)操作系統(tǒng)的提示符

操作系統(tǒng)的外殼

操作系統(tǒng)是由多個(gè)功能模塊組成的龐大、復(fù)雜的軟件系統(tǒng)。任何通用的操作系統(tǒng),都要提供一一個(gè)稱為sel(外殼)的程序,用戶(操作人員)使用這個(gè)程序來操作計(jì)算機(jī)系統(tǒng)進(jìn)行工作。

DOS中有一個(gè) 程序command.com,這個(gè)程序在DOS中稱為命令解釋器,也就是DOS系統(tǒng)的shell.

DOS啟動(dòng)時(shí),先完成其他重要的初始化工作,然后運(yùn)行command com, command.com 運(yùn)行后,執(zhí)行完其他的相關(guān)任務(wù)后,在屏幕上顯示出由當(dāng)前盤符和當(dāng)前路徑組成的提示符,比如:“c:\” 或“c:windows"等,然后等待用戶的輸入。

用戶可以輸入所要執(zhí)行的命令,比如,cd、 dir. type 等,這些命令由command執(zhí)行,command 執(zhí)行完這些命令后,再次顯示由當(dāng)前盤符和當(dāng)前路徑組成的提示符,等待用戶的輸入。

如果用戶要執(zhí)行一個(gè)程序, 則輸入該程序的可執(zhí)行文件的名稱,command 首先根據(jù)文件名找到可執(zhí)行文件,然后將這個(gè)可執(zhí)行文件中的程序加載入內(nèi)存,設(shè)置CS:IP指向程序的入口。此后,command 暫停運(yùn)行,CPU運(yùn)行程序。程序運(yùn)行結(jié)束后,返回到command中,command再次顯示由當(dāng)前盤符和當(dāng)前路徑組成的提示符,等待用戶的輸入。

在DOS中,command處理各種輸入:命令或要執(zhí)行的程序的文件名。我們就是通過command來進(jìn)行工作的。

匯編程序從寫出到執(zhí)行的過程

到此,完成了一個(gè)匯編程序從寫出到執(zhí)行的全部過程。我們經(jīng)歷了這樣一個(gè)歷程:

編程一1.asm→編譯→1.obj-連接→1.exe→加載→內(nèi)存中的程序一運(yùn)行

程序過程的跟蹤

現(xiàn)在我們知道,在DOS中運(yùn)行一個(gè)程序的時(shí)候,是由command將程序從可執(zhí)行文件中加載入內(nèi)存,并使其得以執(zhí)行。但是,這樣我們不能逐條指令地看到程序的執(zhí)行過程,因?yàn)閏ommand的程序加載,設(shè)置CS:IP指向程序的入口的操作是連續(xù)完成的,而當(dāng)CS:IP指向程序的入口, command就放棄了CPU 的控制權(quán), CPU立即開始運(yùn)行程序, 直至程序結(jié)束。

為了觀察程序的運(yùn)行過程,可以使用Dcbug. Debug 可以將程序加載入內(nèi)存,設(shè)置CS:IP指向程序的入口,但Debug 并不放棄對CPU的控制,這樣,我們就可以使用Debug的相關(guān)命令來單步執(zhí)行程序,查看每一條指令的執(zhí)行結(jié)果。

[BX]和loop指令

?[bx]和內(nèi)存單元的描述

[bx]是什么呢?和10有些類似,[01表示內(nèi)存單元,它的偏移地址是0. 比如在下面的指令中(在Debug中使用):

mov ax, [0]

將一個(gè)內(nèi)存單元的內(nèi)容送入ax,這個(gè)內(nèi)存單元的長度為2字節(jié)(字單元),存放一個(gè)字,偏移地址為0,段地址在ds中。

mov al, [0]

將一個(gè)內(nèi)存單元的內(nèi)容送入al, 這個(gè)內(nèi)存單元的長度為1字節(jié)(字節(jié)單元),存放一個(gè)字節(jié),偏移地址為0,段地址在ds中。

要完整地描述一個(gè)內(nèi)存單元,需要兩種信息:1內(nèi)存單元的地址:2內(nèi)存單元的長度(類型)。

用[0]表示一個(gè)內(nèi)存單元時(shí),0表示單元的偏移地址,段地址默認(rèn)在ds中,單元的長度(類型)可以由具體指令中的其他操作對象(比如說寄存器)指出。

[bx]同樣也表示一個(gè)內(nèi)存單元,它的偏移地址在bx中,比如下面的指令:

mov ax, [bx]

將一個(gè)內(nèi)存單元的內(nèi)容送入ax, 這個(gè)內(nèi)存單元的長度為2字節(jié)(字單元),存放一個(gè)字,偏移地址在bx中,段地址在ds中。

mov al, [bx]

將一個(gè)內(nèi)存單元的內(nèi)容送入a1, 這個(gè)內(nèi)存單元的長度為1字節(jié)(字節(jié)單元),存放一個(gè)字節(jié),偏移地址在bx中,段地址在ds中。

loop英文單詞“l(fā)oop”有循環(huán)的含義,顯然這個(gè)指令和循環(huán)有關(guān)

我們定義的描述性的符號:“()”

(ax)表示ax中的內(nèi)容、(al)表示 al中的內(nèi)容:

(20000H)表示內(nèi)存20000H單元的內(nèi)容(O中的內(nèi)存單元的地址為物理地址);((ds)*16+(bx))表示:

ds中的內(nèi)容為ADR1, bx中的內(nèi)容為ADR2,內(nèi)存ADR1X16+ADR2單元的內(nèi)容。也可以理解為: ds中的ADRI作為段地址,bx中的ADR2作為偏移地址,內(nèi)存ADR1:ADR2單元的內(nèi)容。

注意,“()” 中的元素可以有3種類型:寄存器名:段寄存器名:內(nèi)存單元的物理地址(一個(gè) 20位數(shù)據(jù))。比如:

(ax)、(ds)、 (al)、 (ex)、 (20000H)、((ds)*16+(bx))等是正確的用法:

(2000:0)、((ds): 1000H)等是不正確的用法。

我們看一下(X)的應(yīng)用,比如,

(1) ax 中的內(nèi)容為0010H,可以這樣來描述: (ax)= 0010H;

(2) 2000:1000 處的內(nèi)容為0010H,可以這樣來描述: (21000H)= 0010H;

(3)對于mov ax,[2]的功能,可以這樣來描述: (ax)= ((ds)*16+2);

(4)對于mov [2],ax的功能,可以這樣來描述: ((ds)*16+2)=(ax);

(5) 對于add ax,2的功能,可以這樣來描述: (ax)=(ax)+2;

(6)對于add ax,bx的功能,可以這樣來描述: (ax)=(ax)+(bx);

(7)對于push ax的功能,可以這樣來描述:

(sp)=(sp)-2

((ss)*16+(sp))=(ax)

(8)對于pop ax的功能,可以這樣來描述:

(ax)=((ss)*16+(sp))

(sp)=(sp)+2

“(X)”所表示的數(shù)據(jù)有兩種類型:1字節(jié);2字。是哪種類型由寄存器名或具體的運(yùn)算決定,比如:

(a1)、(b1)、 (c1)等得到的數(shù)據(jù)為字節(jié)型; (ds)、 (ax)、 (bx)等 得到的數(shù)據(jù)為字型。

(a1)=(20000H),則(20000H)得 到的數(shù)據(jù)為字節(jié)型; (ax)=(20000H),則20000HD)得 到的數(shù)據(jù)為字型

約定符號idata表示常量

我們在Debug中寫過類似的指令: mov ax,[0], 表示將ds:0 處的數(shù)據(jù)送入ax中。指令中,在“[...]”里用一個(gè)常量0表示內(nèi)存單元的偏移地址。以后,我們用idata 表示常量。比如:

mov ax,[idata]就代表mov ax,[1]、mov ax,[2]、mov ax,[3]等。mov bx,idata就代表mov bx,1、mov bx,2、mov bx,3等。

mov ds,idata就代表movds,1、movds,2等,它們都是非法指令。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第3章、寄存器(內(nèi)存訪問) 3.1 內(nèi)存中字的存儲 字單元:存放一個(gè)字型數(shù)據(jù)(16位)的內(nèi)存單元,由兩個(gè)連續(xù)的內(nèi)存...
    BoL0150閱讀 1,132評論 0 0
  • 什么是Debug? Debug是DOS、Windows都提供的實(shí)模式(8086方式)程序的調(diào)試工具。使用它,可以查...
    4d29e26b2bce閱讀 507評論 0 0
  • 棧是一種具有特殊的訪問方式的存儲空間。它的特殊性就在于,最后進(jìn)入這個(gè)空間的數(shù)據(jù),最先出去。 可以用一個(gè)盒子和3本書...
    4d29e26b2bce閱讀 325評論 0 0
  • 匯編語言的一些注意點(diǎn) 匯編語言是直接在硬件之上工作的編程語言。 CPU(Central Processing Un...
    BackSpace8閱讀 1,849評論 0 1
  • 棧段 對于8086PC機(jī),在編程時(shí),可以根據(jù)需要,將組內(nèi)存單元定義為一個(gè)段。我們可以將長度為N(N<=64KB)的...
    4d29e26b2bce閱讀 225評論 0 1

友情鏈接更多精彩內(nèi)容