匯編語言程序設計 實驗1 用機器指令和匯編指令編程


匯編語言程序設計 實驗1 用機器指令和匯編指令編程

一、實驗目的

  1. 熟練掌握使用debug工具編寫和調試x86匯編命令的方法
  2. 掌握8086CPU、寄存器、內存的基礎知識
  3. 理解並掌握內存中多字節數據的存放:小端法
  4. 理解並掌握「棧」內存空間的特性和使用
  5. 掌握指令mov, add, sub, jmp, push, pop的基礎用法

二、實驗內容及結果

(一)匯編語言(王爽第4版)實驗1 查看CPU和內存,用機器指令和匯編指令編程

1、實驗准備

(1)DOSBox的安裝

超級貼心的老師已經准備好了Windows平台下的下載安裝程序(DOSBox0.74-3-win32-installer),以及Mac OS下的安裝鏡像(DOSBox-0.74-3-2.dmg),下載好之后一步一步按照老師的教程也可以順利使用啦!

鏈接:https://pan.baidu.com/s/1xkV_L_4G42AvKPidYu_czA   提取碼:1314

(2)Debug的使用
① 常用的Debug功能

R命令:查看、改變CPU寄存器的內容

D命令:查看內存中的內容

E命令:改寫內存中的內容

U命令:將內存中的機器指令翻譯成匯編指令

T命令:執行一條機器指令

A命令:以匯編指令的格式在內存中寫入一條機器指令

P命令:執行匯編程序,單步跟蹤。(與T命令的不同:P命令不會跟蹤進入子程序或軟中斷。)

Q命令:退出Debug,回到DOS狀態。

② 在DOSbox中進入Debug

輸入命令

mount d: d:\masm

如下圖所示,可以在指定盤中運行Debug程序

③用R命令查看、改變CPU寄存器的內容

需要注意的是CS和IP的值,CS=073F,IP=0100,也即內存073F:0100處的指令為CPU當前要讀取、執行的指令。

Debug還列出了CS:IP所指向的內存單元處所存放的機器碼,並將它翻譯成匯編指令,此處CS:IP所指向的內存單元為073F:0100,存放的機器碼為0000,對應的匯編指令為ADD [BX+SI],AL。感覺這條指令挺特別的就在網上搜了搜,就是把al的值與ds:[bx+si]的值相加,然后將結果放到ds:[bx+si]中(但其實好像沒啥意義,就是0000反編譯而成的TAT)。右下角還有一個DS:0000=CD,網上查了之后得知:DS:0000就是這個DS的數據段偏移量0000的地址,[0000]就是進階尋址這個數據,看到是CD。

同時,R命令也可以用來改變CPU寄存器的內容,如下圖所示:

④用D命令查看內存中的內容

用D命令直接查看,將列出Debug預設的地址處的內容,如圖所示:

可以用”d段地址:偏移地址“的格式來查看內存某處的內容,如圖所示:

⑤用E命令改寫內存中的內容

可以用E命令改寫內存中的內容,如圖所示:

⑥用U命令將內存中的機器指令翻譯成匯編指令

可以用U命令將內存中的機器指令翻譯成匯編指令,如圖所示:

⑦用T命令執行一條機器指令

可以用T命令執行一條機器指令,如圖所示:

(A指令的使用方法將在實驗任務中展示。)

2、實驗任務

(1)使用Debug,將下面的程序段寫入內存,逐條執行,觀察每條指令執行后CPU中相關寄存器中內容的變化。

 機器碼        匯編指令
b8 20 4e    mov ax,4E20H
05 16 14    add ax,1416H
bb 00 20    mov bx,2000H
01 d8        add ax,bx
89 c3        mov bx,ax
01 d8        add ax,bx
b8 1a 00    mov ax,001AH
bb 26 00    mov bx,0026H
00 d8        add al,bl
00 dc        add ah,bl
00 c7        add bh,al
b4 00        mov ah,0
00 d8        add al,bl
04 9c        add al,9CH

提示,可用E命令和A命令以兩種方式將指令寫入內存。注意用T命令時,CS:IP的指向。

首先用R命令查看當前寄存器內容,如圖所示:

分別用E命令和A命令以兩種方式將指令寫入內存

Ⅰ E命令

Ⅱ A命令

反匯編結果:

執行代碼前需修改CS:IP,以指向指定的內存段,並用R命令查詢是否修改成功:

用T命令執行

由執行過程可以看出,IP的增加值與對應的代碼的機器碼長度有關。

(2)將下面3條指令寫入從2000:0開始的內存單元中,利用這3條指令計算2的8次方。

mov ax,1
add ax,ax
jmp 2000:0003

輸入3條指令,並且修改CS:IP,用R命令檢查:

AX作為累加單元,初始值為0001。JMP為立即數,表示將立即數轉移到IP中,執行結果中IP的值在不斷改變,在執行過程中充當循環的作用,題目所求2的8次方,即使mov ax,ax循環8次,結果如下:

圖中標識處即為求得的2的8次方結果(16進制表示)

(3)查看內存中的內容

PC機主板上的ROM中寫有一個生產日期,在內存FFF00H~FFFFFH的某幾個單元中,請找到這個生產日期並試圖改變它。

由結果可得,生產日期為01/01/92,下面試圖改變這個日期:

由結果可得,生產日期在只讀的地址空間,故只能讀取而不能寫入,也就不能改變它。

(4)向內存從B8100H開始的單元中填寫數據,如:

-e B810:000 01 01 02 02 03 03 04 04

請讀者先填寫不同的數據,觀察產生的現象;再改變填寫的地址,觀察產生的現象。

有圖片欸!!!!!

改變填寫的數據和填寫的地址:

結果顯示,B8100H在顯存地址空間,故在B8100H開始的單元中填寫數據會被讀取並解析為對應的屏幕信息並顯示。

(二)匯編語言(王爽第4版)實驗2 用機器指令和匯編指令編程

1、實驗任務

(1)使用Debug,將下面的程序段寫入內存,逐條執行,根據指令執行后的實際運行情況填空。

mov ax,ffff
mov ds,ax

mov ax,2200
mov ss,ax

mov sp,0100

mov ax,[0]     ;ax=_____
add ax,[2]     ;ax=_____
mov bx,[4]     ;bx=_____
add bx,[6]     ;bx=_____

push ax        ;sp=_____ ; 修改的內存單元的地址是_____內容為_____
push bx        ;sp=_____ ; 修改的內存單元的地址是_____內容為_____
pop ax         ;sp=_____ ; ax=_____
pop bx         ;sp=_____ ; bx=_____

push [4]       ;sp=_____ ; 修改的內存單元的地址是_____內容為_____
push [6]       ;sp=_____ ; 修改的內存單元的地址是_____內容為_____

為了便於驗證實驗結果,對「2. 實驗任務」的(1)做如下兩點調整:
① 在使用 a 命令輸入指令調試之前,先使用 e 命令將內存單元 0022:0 ~0022:7連續 8 個字節數據修改為 50H, 51H, 52H, 53H, 54H, 55H, 56H, 57H
② 將 P74 實驗任務(1)中第1行的 mov ax, ffff 改為 mov ax, 0022 

過程如下所示:

結果如下圖所示:

在這里執行mov ss,ax時,mov sp,0100也跟着執行了

執行push時,先sp-2,再將數據放入到棧中

執行pop時,先取出數據到寄存器,然后sp+2

需要特別注意的是,ss:sp始終指向棧頂元素

 故需填內容為:

mov ax,[0]     ;ax=5150H
add ax,[2]     ;ax=A4A2H
mov bx,[4]     ;bx=5554H
add bx,[6]     ;bx=ACAAH

push ax        ;sp=00FEH ; 修改的內存單元的地址是2200:00FE內容為A4A2H
push bx        ;sp=00FCH ; 修改的內存單元的地址是2200:00FC內容為ACAAH
pop ax         ;sp=PPFEH ; ax=ACAAH
pop bx         ;sp=00FCH ; bx=A4A2H

push [4]       ;sp=00FEH ; 修改的內存單元的地址是2200:00FE內容為5554H
push [6]       ;sp=00FCH ; 修改的內存單元的地址是2200:00FC內容為5756H

(2)仔細觀察圖3.19中的實驗過程,然后分析:為什么2000:0~2000:f中的內容會發生改變?

由此可以看出:沒有數據可以作為棧用

當把2000:0~2000:f作為棧的時候,系統會把寄存器的一些數據暫存在棧中,比如數據CS:IP先后得到暫存。

進一步執行代碼后發現,棧還可以暫存AX寄存器的數據,對應標志寄存器。

其中,前3行匯編指令的功能分別為:

第1行:為AX寄存器賦值2000;第2行:初始化棧基地址為ax中的值;第3行:初始化棧頂偏移地址為10。

需要特別注意的是:mov ss,ax和mov sp,0100先后一起執行。

基於單步調試觀察到的變化,且經查詢可得,DOS下系統只有一個棧,當外部操作未設置棧的時候,系統已經有了一個棧在保存相關數據;當外部操作設置棧的時候,暫存的數據就被保存在新設置的棧中,也即push前,系統已經在暫存數據了,但由於是暫存的,故其內容會發生改變。

三、實驗總結

1、實驗1總結:實驗中印象最深刻的是Jmp立即數,其表示立即數轉移到ip中,短短一條指令卻可以實現指令的循環和跳躍執行。以及!才發現高級語言是多么的方便和簡單!!!!QAQ

2、實驗2總結:實驗中發現,類似mov sp,10H這樣的指令,可以對棧多很多的動作(有點神奇)。

同時,經查詢得到,DOS下,棧只有一個,其可以暫存很多數據,如CS:IP,AX,標志寄存器,但是是否暫存更多的數據仍需要進一步的學習與探索!!!


免責聲明!

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



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