操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    ello大家好,我是程序員cxuan!這篇文章我們來進(jìn)行實(shí)際操作一下Debug。

    我們以后將會用到很多 Debug 命令,這里我們先來熟悉一下它們。

    Debug 是什么

    Debug 是 Windows / Dos 操作系統(tǒng)提供的一種功能。使用 Debug 能讓我們方便查看 CPU 各種寄存器的值、內(nèi)存情況,方便我們調(diào)試指令、跟蹤程序的運(yùn)行過程。

    接下來我們會用到很多 debug 命令,但是使用這些命令的前提是,你需要在電腦上安裝一下 debug,Windows/Mac 都可以安裝,獲取鏈接我已經(jīng)給你找出來了。阿,忘記說了,我們這里使用的是 Dos box來模擬匯編的操作環(huán)境。

    傳送門(Mac 和 Windows 都是):https://www.dosbox.com/download.php?main=1

    下載完成后打開 DosBox ,打開之后是這樣的。

    此時我們輸入 debug 命令應(yīng)該提示的是

    因?yàn)槲覀冞€沒有進(jìn)行連接和掛載,此時我們執(zhí)行

     mount c D:\debug
    

    執(zhí)行這條命令時,你需要現(xiàn)在 D 盤下創(chuàng)建一個 debug 文件夾,然后我們掛載到 debug 下面。

    并且執(zhí)行 C: 切換到 C 盤路徑下。

    此時我們就可以執(zhí)行 debug 命令了。

    這里需要注意一點(diǎn),我在 Windows 10 系統(tǒng)下搭建 Debug 環(huán)境時,在掛載完成后輸入 debug ,還是提示 Illegal command:debug ,此時你需要再下載一個 debug.exe ,貼心的我也把下載地址給你了。

    下載地址:https://pan.baidu.com/s/177arSA34plWqV-iyffWpEw#list/path=%2F 密碼:3akd

    需要下載里面的 debug.exe,然后把它放在你掛載的路徑下,這里我掛載的路徑時 D 盤下的 debug 文件夾。

    放置完成之后,再輸入 debug 就可以了。


    因?yàn)槊看未蜷_ Dosbox 都會執(zhí)行上面這些命令,真的好煩,那怎么辦呢?一個簡單的辦法是在 Dosbox 安裝路徑下找到

    打開之后,在末尾鍵入

    就 OK 了,下次直接打開 Dosbox ,會默認(rèn)執(zhí)行這三條命令,至此,就是我搭建 Dosbox 遇到的所有問題了。

    Debug 實(shí)戰(zhàn)


    玩兒匯編得學(xué)會用 Debug ,Debug 是一種調(diào)試程序,通過 Debug 能讓我們能夠看到內(nèi)存值,跟蹤堆棧情況,看到寄存器所暫存的內(nèi)容等,同時也能夠更好地幫助我們理解匯編代碼,所以學(xué)會 Debug ,非常重要,這是一種不可或缺的動手能力。

    下面我們會用到幾種 Debug 命令,這里先簡單介紹下。

    Debug 命令有很多,不過常用的一般就上面這幾個。

    好了,現(xiàn)在我們直接進(jìn)入正題,開始在 Dosbox 上正式進(jìn)行 Debug 操作,首先打開 Dosbox。

    嗯。。。。。。這個界面我們打開很多次了。

    那我寫個命令呢?好吧,沒演示過,下面就來了!

    Debug -r

    親,用 Debug -r 就可以查看和修改 CPU 寄存器內(nèi)容了呢。

    查看寄存器內(nèi)容。

    這里需要注意一下 -r 大小寫的問題,Debug -r 是查看寄存器內(nèi)容。而 -R 則是無效指令。

    上圖列出來了很多寄存器,你可能覺得無從下手,不要亂,我們先從最基本的開始入手,也就是 CS 和 IP,CS(Code Segment)是代碼段寄存器,一般也被稱為段基址,可以認(rèn)為是程序訪問的入口,CPU 需要從 CS 中找到從哪個位置開始取指執(zhí)行,但是我們還不知道要取哪一段,這時候 IP 的作用就體現(xiàn)出來了,IP(Instruction Pointer)就是指令指針寄存器,也叫做偏移地址,它會告訴我們從段基址開始,取哪一段的地址。

    可以使用段基址:偏移地址來確定內(nèi)存中的指定地址。

    這里我們只是簡單聊一下這兩個寄存器的概念,要了解這兩個寄存器的具體作用,可以看筆者的上一篇文章

    使用 -r 也能夠修改寄存器的內(nèi)容,如下所示

    -r 一般的格式是 -r 寄存器,然后系統(tǒng)會進(jìn)行冒號提示,后面就是你要修改的內(nèi)容。

    Debug -d

    使用 -d 指令可以查看內(nèi)存中的內(nèi)容。

    輸出的內(nèi)存值默認(rèn)是按照 CS:IP 的地址開始的,由于 CS 的值默認(rèn)是 073F,而 IP 默認(rèn)是 0100,所以 -d 的內(nèi)存值是 073F:0100 。

    -d 的格式很多,下面只介紹一下常用的幾種格式。

    形似 -d 1000:0 這種 -d 段基址 偏移地址的格式可以產(chǎn)生如下輸出。

    如上圖所示,Debug 會列出指定內(nèi)存單元中的的內(nèi)容。上圖中的每一個 00 都表示 8 位,如果是 4A,那么這八位展開來說就是 0010 1011 。每一行有 16 個 8 位,所以構(gòu)成了 128 位內(nèi)存地址。

    為什么都是 00 呢,因?yàn)閮?nèi)存單元的值沒有被改寫,說白了就是這塊內(nèi)存區(qū)域沒有存值,如何改寫我們后面會說。

    每一行的中間都有一個 -,這個是為了便于我們閱讀來設(shè)置的,- 號前后都有 8 個內(nèi)存單元,這樣便于查看。

    右側(cè)幾個 ...... 表示每個內(nèi)存單元可顯示的 ASCII 碼字符,因?yàn)閮?nèi)存沒有值,所以也沒有對應(yīng)的 ASCII 碼。我們可以數(shù)一下,每行有 16 個 . ,這表示每一個 00 都對應(yīng)了一個 ASCII 碼。

    我們可以使用 -d 1000:9 這種 -d 段基址:起始偏移地址 格式來顯示從 1000 的第幾位開始。

    Debug 從 1000:9 開始,一直到 1000:88,一共是 128 個字節(jié),第一行中的 1000:0 ~ 1000:8 中的內(nèi)容沒有顯示。

    還可以使用 -d 1000:0 9 這種 -d 段基址:起始偏移地址 結(jié)尾偏移地址的格式來輸出。

    還可以是使用 -d 偏移地址來在不指定段基址的情況下,查看內(nèi)存值。

    Debug -e

    上面說的都是查看內(nèi)存中指定位置或者區(qū)域的值,下面我們要來改寫一下內(nèi)存值。

    使用 -e 可以改寫內(nèi)存值,比如我們想要改寫 1000:0 ~ 1000:f 中的內(nèi)容,可以使用 -e 1000:0 0 1 2 3 4 5 6 7 8 9 0 a b c d e f 這種方式,如下圖所示。

    這里需要注意下,在進(jìn)行 -e 改寫的時候,每個值中間都有一個空格,如果沒有空格的話,會當(dāng)做一個內(nèi)存值來看待。

    然后用 -d 1000:0 看到我們剛改寫的內(nèi)存值。

    還可以使用提問的方式來逐個修改從某一地址開始的內(nèi)存單元的內(nèi)容。

    還是用 1000:100 來舉例子,輸出 -e 1000:100 后按下回車鍵。

    如上圖所示,可以看到我們先輸入了一次 -e 1000:100 這個指令,然后按下了回車鍵。

    注意,如果這里你按下了回車鍵,就相當(dāng)于整個 -e 改寫的過程已經(jīng)完成。

    如果你想要繼續(xù)改寫后面內(nèi)存中的值,你需要按下空格鍵。

    我們改寫了 1000:100 之后的內(nèi)存值,然后使用 -d 1000:100 查看我們改寫的內(nèi)容是否生效。

    -e 命令還可以支持寫入字符,比如我們可以向 1000:0 這個位置開始寫入數(shù)值和字符,-e 1000:0 1 'a' 2 'b' e 'c' 。

    如上圖所示,當(dāng)我們向內(nèi)存寫入字符 'a' 'b' 'c' 的時候,會自動轉(zhuǎn)換為 ASCII 碼進(jìn)行存儲,在最右側(cè)可以找到剛剛寫入的字符。

    Debug -u

    如何向內(nèi)存中寫入一段機(jī)器碼呢?比如我們想要在內(nèi)存中寫入一段機(jī)器碼。

    我們可以使用 -e 來進(jìn)行寫入,向內(nèi)存中寫入 b8 01 00 b9 02 00 01 c8 這個機(jī)器碼,如下所示

    我們使用 -e 寫入之后,使用 -d 查看內(nèi)存值,可以發(fā)現(xiàn)我們剛剛寫入的值,但是卻看不到機(jī)器碼,所以機(jī)器碼該如何看呢?

    別急,還有個 -u 命令,這個就是看機(jī)器碼的,如下圖所示,我們使用 -u 命令顯示我們寫入的機(jī)器碼。

    可以看到 1000:0000 ~ 1000:0006 這個內(nèi)存地址使我們寫入的機(jī)器碼,-u 這個命令就是將內(nèi)存單元的內(nèi)容翻譯為匯編指令并顯示。

    -u 輸出的結(jié)果分為三部分顯示:

    • 最左側(cè)是每一條機(jī)器指令的地址;
    • 中間是機(jī)器指令;
    • 最右側(cè)是機(jī)器指令執(zhí)行的匯編指令。

    1000:0 處存放的是寫入的機(jī)器碼 B8 01 00 組成的機(jī)器指令,對應(yīng)的匯編指令是 MOV AX,0001。

    1000:0003 處存放的是寫入的機(jī)器碼 B9 02 00 組成的機(jī)器指令,對應(yīng)的匯編指令是 MOV CX,0002。

    1000:0006 處存放的是寫入的機(jī)器碼 C1 C8 所組成的機(jī)器指令,對應(yīng)的匯編指令是 add ax,cx。

    Debug -t

    上面介紹的一系列指令包括我們上面提到的 Debug -e 機(jī)器碼都是向內(nèi)存中進(jìn)行寫入,那么如何執(zhí)行這些指令呢?

    我們可以使用 Debug -t 來執(zhí)行寫入的指令。使用 Debug -t 可以執(zhí)行由 CS:IP 指向的指令。

    既然是 -t 能夠執(zhí)行從 CS:IP 指向的命令,所以我們有必要將 CS:IP 指向 1000:0(因?yàn)槲覀兦懊鎸⒅噶顚懺诹?1000:0 處)。

    首先我們需要執(zhí)行 -r cs 1000 ,-r ip 0 把 CS:IP 賦值為 1000:0。

    然后執(zhí)行 -t 指令,下圖是已經(jīng)執(zhí)行過的指令截圖。

    可以看到,執(zhí)行完 -t 指令之后,MOV AX,0001 這條指令被執(zhí)行,當(dāng)前 AX 寄存器的內(nèi)容變?yōu)榱?0001,這條匯編指令的意思就是把 0001 移動到 AX 寄存器中。

    繼續(xù)執(zhí)行 -t 之后,我們可以看到寄存器的變化。

    Debug -a

    畢竟機(jī)器指令不是那么好懂,寫入很不方便,所以有沒有辦法能夠支持我們直接寫入?yún)R編指令呢?還真有,Debug 提供了 -a 這種方式來實(shí)現(xiàn)匯編指令的寫入。如下圖所示

    可以看到,我們使用了 -a 命令來對 1000:0 進(jìn)行寫入,分別輸入 mov ax,1 mov bx,2 mov cx,3 add ax,bx add ax,cx add ax,ax 指令,然后按回車進(jìn)行確定執(zhí)行。

    我們使用 -d 1000:0 f 可以看到從偏移地址 0 處開始的第 f 個內(nèi)存指令(因?yàn)樽畲髮懭氲牡刂分皇?f)。

    上圖中的 1000:000F 為什么有值呢,因?yàn)槲覀兩厦嬉呀?jīng)執(zhí)行過這個寫入了。

    另外,使用 -a 可以從一個預(yù)設(shè)的地址處開始輸入指令。

    總結(jié)


    今天和大家聊了一下 Debug 的基本用法,主要包括

    • -r 查看、修改寄存器中的內(nèi)容
    • -d 查看內(nèi)存中的指令
    • -e 修改內(nèi)存中的內(nèi)容
    • -u 可以將內(nèi)存中的內(nèi)容解釋為機(jī)器指令和對應(yīng)的匯編指令
    • -t 執(zhí)行 CS:IP 處的指令
    • -a 以匯編得形式向內(nèi)存寫入內(nèi)容

    匯編指令的選項(xiàng)有很多,上面介紹的這些屬于經(jīng)常用到的指令,這些指令要能夠熟練使用。

    【實(shí)驗(yàn)具體內(nèi)容】

    1.使用Debug,將程序(見實(shí)驗(yàn)源代碼)寫入內(nèi)存,逐條執(zhí)行,觀察每條指令執(zhí)行后,CPU中相關(guān)寄存器中內(nèi)存的變化。

    2.將下面三條指令(見實(shí)驗(yàn)源代碼)寫入從2000:0開始的內(nèi)存單元中,利用這三條指令計(jì)算2的8次方。

    3.查看內(nèi)存中存有的PC機(jī)主板上的ROM生產(chǎn)日期并試圖修改。

    4.觀察下圖中的實(shí)驗(yàn)過程,分析為何2000:0~2000:f中的內(nèi)容會發(fā)生改變

    【第一個實(shí)驗(yàn)】


    (1.1)實(shí)驗(yàn)源代碼(粘貼源代碼):

    機(jī)器碼 匯編指令

    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

    (1.2)實(shí)驗(yàn)代碼、過程、相應(yīng)結(jié)果(截圖)并對實(shí)驗(yàn)進(jìn)行說明和分析:

    Win10下可以借用Dosbox調(diào)試Debug,如下圖

    用Debug下的-d命令查看1000:0之后128個內(nèi)存單元中的內(nèi)容

    用Debug下的-a命令以匯編語言的形式寫入從1000:0開始的內(nèi)存單元中

    使用Debug下的-d命令查看1000:0內(nèi)存中的內(nèi)容核對

    在-t命令之前注意CS:IP當(dāng)前指向,這里指向073F:0102,需要修改其指向

    使用Debug下的-r命令修改CS:IP指向,如下圖

    使用Debug下的-t命令逐次執(zhí)行1000:0中的指令,截圖如下

    歷次-t命令下CS:IP指向和寄存器中內(nèi)容如下:

    CS:IP AX BX

    1000:0000 0000 0000

    1000:0003 4E20 0000

    1000:0006 6236 0000

    1000:0009 6236 2000

    1000:000B 8236 2000

    1000:000D 8236 8236

    1000:000F 046C 8236

    1000:0012 001A 8236

    1000:0015 001A 0026

    1000:0017 0040 0026

    1000:0019 2640 0026

    1000:001B 2640 4026

    1000:001D 0040 4026

    1000:001F 0066 4026

    1000:0021 0002 4026


    (2.1)實(shí)驗(yàn)源代碼:

    mov ax,1 (從2000:0開始的內(nèi)存單元)

    add ax,ax

    jmp 2000:0003 (觀察跳到什么地方了?)

    (2.2)實(shí)驗(yàn)代碼、過程、相應(yīng)結(jié)果(截圖)并對實(shí)驗(yàn)進(jìn)行說明和分析:

    源代碼寫入過程類似上面1.2的過程,這里不再贅述,僅展示截圖

    通過jmp指令,在執(zhí)行一次mov ax,1后程序?qū)⒃赼dd ax,ax和jmp 2000:0003之間循環(huán)往復(fù),直到計(jì)算出2的8次方

    (下面忽略中間過程,僅關(guān)注最終結(jié)果即可)

    指令執(zhí)行過程紛繁復(fù)雜!


    (3.1)實(shí)驗(yàn)代碼、過程、相應(yīng)結(jié)果(截圖)并對實(shí)驗(yàn)進(jìn)行說明和分析:

    由于dosbox模擬一個真實(shí)的電腦環(huán)境,故01/01/92與主板ROM不同可以理解。


    【第二個實(shí)驗(yàn)】

    (1.1)實(shí)驗(yàn)源代碼(粘貼源代碼):

    mov ax,ffff

    mov ds,ax

    mov ax,2200

    mov ss,ax

    mov sp,0100

    mov ax,[0] ;ax=C0EA

    add ax,[2] ;ax=C0FC

    mov bx,[4] ;bx=30F0

    add bx,[6] ;bx=6021

    push ax ;sp= 00FE ;修改的內(nèi)存單元的地址是2200:00FE 內(nèi)容為C0FC

    push bx ;sp= 00FC ;修改的內(nèi)存單元的地址是2200:00FC 內(nèi)容為6021

    pop ax ;sp= 00FE ;ax=6021

    pop bx ;sp=0100 ;bx=C0FC

    push [4] ;sp= 00FE ;修改的內(nèi)存單元的地址是2200:00FE 內(nèi)容為30F0

    push [6] ;sp= 00FC ;修改的內(nèi)存單元的地址是2200:00FC 內(nèi)容為2F31


    (1.2)實(shí)驗(yàn)代碼、過程、相應(yīng)結(jié)果(截圖)并對實(shí)驗(yàn)進(jìn)行說明和分析:

    修改CS:IP,使之指向2000:0000,并查看當(dāng)前寄存器中內(nèi)容:

    執(zhí)行mov ax,ffff

    執(zhí)行mov ds,ax

    執(zhí)行mov ax,220

    執(zhí)行mov ss,ax,此處忘記截圖,可參考下圖

    執(zhí)行mov sp,0100

    執(zhí)行mov ax,[0]

    執(zhí)行add ax,[2]

    執(zhí)行mov bx,[4]

    執(zhí)行add bx,[6]

    執(zhí)行push ax

    執(zhí)行push bx

    執(zhí)行pop ax

    執(zhí)行pop bx

    執(zhí)行push [4]

    執(zhí)行push [6]

    相關(guān)填空見(1.1)


    (2.1) 實(shí)驗(yàn)源代碼(粘貼源代碼):

    mov ax,1000H

    mov ds,ax

    mov ds,[0]

    add ds,ax


    (2.2)實(shí)驗(yàn)代碼、過程、相應(yīng)結(jié)果(截圖)并對實(shí)驗(yàn)進(jìn)行說明和分析:

    輸入指令過程中,出現(xiàn)錯誤,是因?yàn)閍dd,sub不能對段寄存器ds進(jìn)行操作

    運(yùn)行前三條指令是正常的(*)

    若一定要執(zhí)行add ds,ax,可以采用類似向ds輸入數(shù)據(jù)的方法,如下

    運(yùn)行結(jié)果如下

    由于前面在運(yùn)行不完整程序的前三條指令(*)后,寄存器ds的值發(fā)生變化,導(dǎo)致bx的值發(fā)生變化,進(jìn)而導(dǎo)致add bx,ax運(yùn)行后bx變化,最終導(dǎo)致ds變化,所以在-t命令后截圖中寄存器的值與之前不同,可以通過正式程序之前提前修改ds的值,使之與之前一致來消除影響。


    (3.1)是因?yàn)橹袛嗟挠绊?/p>

    【實(shí)驗(yàn)心得】

    CS:IP指向指令的內(nèi)存單元地址,CPU通過它區(qū)分指令和數(shù)據(jù)。DS存放要訪問數(shù)據(jù)的段地址,CPU是不是也可以通過它來區(qū)分指令和數(shù)據(jù)呢?SS:SP時刻指向棧頂,對于PUSH指令,先進(jìn)行SP=SP-2再送數(shù)據(jù)入棧;POP指令相反,先取出棧內(nèi)數(shù)據(jù)再SP=SP+2。

網(wǎng)站首頁   |    關(guān)于我們   |    公司新聞   |    產(chǎn)品方案   |    用戶案例   |    售后服務(wù)   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區(qū)    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權(quán)所有