《匯編語言》實驗一:用機器指令和匯編指令編程


概要

此次實驗為匯編語言的第一次實驗,難度不大,但是卻是以后所有實驗的基礎,尤其是debug工具的使用,因此會花較大篇幅總結一下此次實驗中涉及的debug用法,剩余部分會根據具體實驗任務總結一下CPU、寄存器、內存的基礎知識以及mov、add、jmp等指令的用法。

目錄 

  1. debug的使用

  2. 實驗任務


debug的使用

查看和改變CPU寄存器內容——R命令

    • 查看格式①:—r<回車>

可以看到,此方法能夠查看所有寄存器的值,如果只想查看某一寄存器的值也可采用下面的格式:

  查看格式②:—r ??<回車> (??代表寄存器名)

用此種方法注意,當冒號出現后應繼續按回車,否則將會改變當前寄存器的內容。

    • 改變格式:—r ??<回車> (??代表寄存器名)

可以看出,此格式和上面查看的第二種格式相同,區別在於:查看在冒號出現后要敲回車,而改變需要在冒號后輸入想要改為的值,示例如下:

ax成功從0000改為了13B1。

    值得注意的是,在debug中命令和參數之間可以沒有分割符(如空格),所以r ax,也可以寫成rax,如下圖所示:

    


 查看和改變內存中的內容——D命令和E命令

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

    我們可以把內存想象成一系列排列整齊有序的盒子,要想查看某個或某段連續的盒子里裝的是什么,我們需要知道起始盒子的具體位置以及其后待查看盒子的個數或者終點盒子的具體位置。由此我們衍生出兩種思路:①地址范圍法:起始位置+終點位置;②個數確定法:起始位置+待查看內存個數

       對於位置的描述可以采用“段地址:偏移地址”的方式,對於個數的描述可以采用“L?”的方式(“?”表示個數,用十六進制表示),下面看一下具體實現:

·    查看格式①:—d 段地址:偏移地址1 偏移地址2<回車>

    
    首先對d命令debug輸出的內容簡要說明一下,debug將輸出三部分內容,左側是每行的起始地址,中間部分是從指定地址開始的若干個內存單元的內容(每行的中間,即第8和第9之間有短線“-”相連,便於查 看),右邊是每個內存單元中的數據對應的可顯示的ASCII碼字符(如果沒有對應的可顯示的ASCII碼字符則輸出“.”)。此格式可以查看從段地址:偏移地址1到段地址:偏移地址2(包含端點)之間的所有內存的內容。
    查看格式②:—d 段地址:偏移地址 L?<回車>(?表示個數,十六進制表示)
    
    此格式可以查看從給定地址開始的給定個數的內存單元的內容。

     以上是2種基本的查看方法,對於d命令還有許多簡化的格式,如:

    這幾種格式中,和①②相比都有不同程度的缺省。其中缺少個數和終點地址的將輸出從起始地址開始的連續128個內存的內容;缺少段地址的將以CS代替,段地址和偏移地址都缺少的將以CS:IP代替。下面分別給出這幾種簡化格式的示例:

查看格式③:

 
這里我指定的地址是0100:0,於是debug就輸出了從0100:0開始的128個內存的內容。
查看格式④:
可以看出,只給一個偏移地址,將輸出從CS:偏移地址開始的128個內存的內容。
查看格式⑤:
輸出了從CS:0010CS:0020間的內存的內容。

 查看格式⑥:

輸出了從CS:0010開始的連續10個內存的內容,尤其注意L后面的數字是用16進制表示的。

  查看格式⑦:

 d后不帶任何參數將默認輸出從CS:IP開始的連續128個內存的內容。

關於d命令還有一個點是,以上任何查看格式后,再次使用—d<回車>將會查看到承接上次查看的最后一個內存單元,顯示接下來128個內存單元的內容。

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

使用e命令改變內存中的內容主要有2種方式,具體如下:

改變格式①:—e 段地址:偏移地址 數據表<回車>

改變格式②:—e 段地址:偏移地址<回車>

     第一種格式的功能是:從指定的地址開始用數據表給定的數據修改存儲單元(數據表中的數據以空格間隔)。第二種格式的功能是以提問的方式逐個地修改從某一地址開始的內存單元的內容。下面看下具體實例:

    改變格式①:

可以看出,從0010:0開始的5個內存單元的內容已經成功被e命令改變了。同樣地,這里的段地址也可省略,當段地址被省略時,段地址默認由CS充當。

    改變格式②:

 此格式的“.”用於提示輸入想要寫入的數據,當然也可以不輸入數據,表示不對當前內存作改變,以空格作為處理結束的標志,之后會跳到下一個內存單元,進行同樣的操作。當所有希望改變的內存都操作完成后按回車鍵結束e命令。


 編寫簡單指令程序及調試的命令——A命令和T、P、G命令

  •  編寫簡單指令程序——A命令

    A命令可以用匯編指令的形式向內存中寫入指令。(其實也可以用e命令以機器指令的方式向內存中寫入指令,不過相對來說更麻煩)語法格式為:a 段地址:偏移地址<回車>

需要注意的是,每條指令后都要按回車,不輸入指令按回車可以結束匯編。

 (此段代碼也同時作為下文調試命令的源代碼)

  • 調試命令——T、P、G命令

T命令和P命令都是單步執行命令,它們有2種語法格式:①t=偏移地址 或 p=偏移地址;②t 或 p;

 第一種語法格式的功能是:從指定的偏移地址處單步執行程序;第二種語法格式的功能是:從CS:IP指向的指令開始單步執行程序 ;t命令和p命令的區別在於:單步執行程序時,如果遇到子程序或中斷服務程序: 若使用t命令,則進入子程序或中斷服務程序,繼續單步執行; 若使用p命令,則把子程序或中斷服務程序當做是一個整體執行。  

 G命令有3種語法格式:①g=偏移地址1 偏移地址2<回車>;②g=偏移地址<回車>;③g 偏移地址<回車>;④g<回車>;

格式①的功能是:運行代碼段中偏移地址1到偏移地址2之間的程序;

格式②的功能是:從指定偏移地址開始執行程序,直到程序結束或遇到INT;

格式③的功能是:從當前偏移地址執行到指定偏移地址之前的指令 ;

格式④的功能是:從CS:IP指向的指令開始執行程序,直到程序結束或遇到INT;

如①的用法:

 需要注意的是,匯編指令是到第二個偏移地址前結束,不包含第二個偏移地址這一內存單元。

 


 

反匯編命令——U命令 

U命令可以將指定內存單元的機器指令反匯編成匯編指令;它有3種格式:①—u 段地址:偏移地址1 偏移地址2<回車>;②—u 地址<回車>:③—u<回車>;

以第一種格式為例:

 向0100:0到0100:3的內存寫入B80300的機器指令,使用u命令可以將它反匯編成匯編指令:MOV ax,0003;

格式②的功能是:從指定地址開始反匯編,默認連續反匯編32字節 

格式③的功能是:從代碼段當前偏移地址開始反匯編,默認連續反匯編32字節 

 


 實驗任務

任務1——將程序段寫入內存

總結:1.debug中數字默認為16進制,加上H反而會出錯

   2.加法運算時,如果運算結果超出寄存器能夠表達的范圍,最高位會被省略

任務2——計算2的8次方

總結:jmp指令可以修改CS和IP,此例中可以達到一個循環的作用,只是這個循環沒有退出條件,是個死循環

任務3——查看主板ROM中的生產日期

找到的日期在ffff5-ffffc,為95年7月3日,試圖用e命令修改其內容,發現不能被改變。原因是ROM為只讀存儲器,不能被修改。

任務4——向顯卡寫入數據

 發現屏幕上出現了四個具有不同顏色不同形狀的圖案。說明每個圖案是由2個字節數據控制的。改變填寫的地址:

 發現同樣的圖案在屏幕的另一個地方被顯示出來。

修改下新地址的第一個字節數據的值:

 發現第一個圖案的形狀改變了,而顏色不變。

修改下新地址的第二個字節數據的值:

 發現第一個圖案的眼神改變了,而形狀不變。

總結:1.顯卡也占據一段內存地址空間,即顯存,向顯存寫入數據,這個數據就會被顯卡輸出到顯示器上。

   2.此例中的圖案由2個字節數據控制,第一個自己控制圖案的形狀,第二個字節控制圖案的顏色。

 


免責聲明!

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



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