日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

GDB调试--以汇编语言为例

發布時間:2023/11/27 生活经验 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 GDB调试--以汇编语言为例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

#rpm -qa |grep? gdb

下載:

安裝

#tar -zxvf

#./configure

#make

使用GDB

以匯編語言調試為例

匯編語言實現CPUID指令

CPUID

cpuid是Intel? Pentinum以上級CPU內置的一個指令(486級以下的CPU不支持),他用于識別某一類型的CPU,

它能返回CPU級別,型號,CPU步進以及CPU字串信息,從此命令也可以得到CPU的緩存和TLB信息


CPUID返回數據類型是在EAX寄存器里定義的,而指令返回的數值則存儲在EAX,EBX,ECX和EDX寄存器中。

返回的信息分兩部分:基本信息與擴展信息。

在EAX輸入0-3參數時,它返回CPU基本信息;

而在EAX輸入0x8000000至ox800000x,他返回的是CPU擴展信息。擴展信息只包括在Pentinum4及以后的CPU上。


CPU級別???????? 基本信息?? 擴展信息
486及以前的CPU????? 不可用??? 不可用
Pentium??????? 0x1??? 不可用
Pentium Pro,Pentium 2??? 0x2??? 不可用
Pentium 3????? 0x3??? 不可用
Pentium 4????? 0x2??? 0x80000004
Xeon(至強)????? 0x2??? 0x80000004


代碼

cpuid.s

#cpuid.s Sample program to extract the processor Vendor ID                
.section .data                
output:                   .ascii "The processor Vendor ID is 'xxxxxxxxxxxx'\n"
.section .text                
.globl _start                
_start:                   movl $0, %eax                   cpuid                   movl $output, %edi                   movl %ebx, 28(%edi)                   movl %edx, 32(%edi)                   movl %ecx, 36(%edi)                   movl $4, %eax                   movl $1, %ebx                   movl $output, %ecx                   movl $42, %edx                   int $0x80                   movl $1, %eax                   movl $0, %ebx                   int $0x80

? 匯編

使用GNU匯編器

#as -o cpuid.o cpuid.s

使用GNU鏈接器

#ld -o cpuid cpuid.o

運行程序

#./cpuid

輸出


調試

為了調試匯編語言程序,必須使用-gstabs參數重新匯編代碼

#as -gstabs -o cpuid.o cpuid.s

#ld -o cpuid cpuid.o

使用-gstabs參數在可執行文件中添加了附加信息,所以新產生的文件會大些

如果沒有必要不要使用調試信息


運行

在gdb內運行

#gdb cupid

GNU調試器啟動,把程序加載到內存,使用run命令(簡化r也可以)從gdb內運行程序


可見調試器內的運行和從命令行直接運行一樣


斷點

匯編語言中指定斷點時,必須指定對于最近的標簽的相對位置,上述代碼中只有一個標簽,所以每個斷點必須依據_start指定。

break(簡化的b)命令格式 break * label+offset

break 函數名

break 行號

break 文件名:行號

break 文件名:函數名

break +偏移量

break -偏移量

break *地址

label是被引用的源代碼中的標簽

offset是應該停止的地方距離標簽的行數

break * _start

*_start參數指定了斷點,該參數指定_start標簽后的第一條指令碼。

run或者(簡化的r)啟動程序,暫停在第一條指令碼處。

單步

使用next(簡化的n)或者step(簡化的s)命令單步調試

注意:s會步入調用的函數,類似于VS中的F11,而n類似于VS中的F10

每個next或者step命令執行下一行代碼

繼續運行

使用continue(或者c)按正常方式繼續運行,類似于VS中的F5


查看數據

info? registers?? 查看所有寄存器的值

print (或者p)?? 顯示特定寄存器或者來自程序的變量值

p $eax??????????? 顯示寄存器的內容

p/格式? 變量

格式

p/t??? 顯示為2進制數

p/o?? 顯示為8進制數

p/d?? 顯示為10進制數

p/u?? 顯示為無符號10進制數

p/x?? 顯示為16進制數

p/a?? 地址

p/c?? 顯示為字符

p/s?? 顯示為字符串

p/f??? 浮點小數

p/i??? 顯示為機器語言(僅在顯示內存的x命令中可用)

程序指針可以寫為$pc或者$eip,因為Intel IA-32架構中的程序指針名為eip

p $pc

p $eip

x???????? 顯示特定的內存位置內容

x/格式 地址

x命令顯示特定內存位置的值。

x命令的格式 x/nyz

n是要顯示的字段數;

y是輸出格式同之前的p

z是要顯示的字段長度:

b??????? 字節

h??????? 半字(2字節)

w?????? 字(4字節)默認值

g??????? 雙字(8字節)

例如:

x $pc

x/i $pc

此處x/i意為顯示匯編指令

也有反匯編命令disassemble(或者disas)

格式:

disas????????????????????????????????????

disas?????? 程序計數器

disas?????? 開始地址? 結束地址

由此可見,在cpuid指令執行之前,EBX,ECX,EDX寄存器都是0,之后他們包含從廠商ID字符串來的值。


使用x命令顯示位于output變量前42個字節的內存位置的值(&符號表明是一個內存位置):

GDB的數據顯示格式

x 按十六進制格式顯示變量。
d 按十進制格式顯示變量。
u 按十六進制格式顯示無符號整型。
o 按八進制格式顯示變量。
t 按二進制格式顯示變量。
a 按十六進制格式顯示變量。
c 按字符格式顯示變量。
f 按浮點數格式顯示變量。


查看寄存器和內存

1) info args
打印出當前函數的參數名及其值。
2)info locals
打印出當前函數中所有局部變量及其值。
3)info catch
打印出當前的函數中的異常處理信息。
4)源代碼的內存
你可以使用info line命令來查看源代碼在內存中的地址。info line后面可以跟“行號”,“函數名”,“文件名:行號”,“文件名:函
數名”,這個命令會打印出所指定的源碼在運行時的內存地址,如:
(gdb) info line tst.c:func
Line 5 of "tst.c" starts at address 0x8048456 <func+6> and ends at 0x804845d <func+13>.
5)info break
查看斷點信息。
6)info threads
看正在運行程序中的線程信息
7)info registers
查看寄存器的情況。(除了浮點寄存器)
8)info all-registers
查看所有寄存器的情況。(包括浮點寄存器)
9)info registers <regname >
查看所指定的寄存器的情況。

例如:info registers ebp

10)info frame或者i f
這個命令會打印出更為詳細的當前棧層的信息,只不過,大多數都是運行時的內內
地址。比如:函數地址,調用函數的地址,被調用函數的地址,目前的函數是由什么
樣的程序語言寫成的、函數參數地址及值、局部變量的地址等等

11)(gdb) disassemble func

disassemble可以查看源程序的當前執行時的機器碼,這個命令
會把目前內存中的指令dump出來

12)list

用list命令來打印程序的源代碼

13)x

可以使用examine命令(簡寫是x)來查看內存地址中的值.

x/3uh 0x54320表示,從內存地址0x54320讀取內容,h表示以雙字節為一個單位,3表示三個單位,u表示按十六進制顯示。

x/48xw? $ebp?? 也可以一樣顯示改寄存器或者用上述方法按寄存器的地址

參考:GDB查看棧信息

查看進程

info proc

查看棧幀

bt

backtrace

info stack

where

都是一樣的只是別名而已

bt? 顯示所有棧幀

bt N? 顯示開頭N個棧幀

bt -N 顯示最后N個棧幀

bt full 顯示棧幀+局部變量

bt full N? N同前

監視

eatch <表達式>

<表達式>發生變化時暫停運行,此處<表達式>是常量或變量等

awatch <表達式>

<表達式>被訪問,改變時暫停運行

nwatch <表達式>

<表達式>被訪問時暫停運行

delete<編號>

刪除監視點

改變變量的值

set variable <變量><表達式>

例如:

(gdb) p? options

$7=1

(gdb)set variable options=0

(gdb)print options

$8=0

GDB命令

1)單步調試:

n (next),

ni(nexti) 執行下一行(以匯編代碼為單位)

s(step 跟n的區別,s進入到函數內)

si(stepi) 執行下一行(以匯編代碼為單位)

u(until)執行到指定行

2)恢復操作:c(continue或者cont) 直到遇到下個斷點

3)臨時斷點: tbreak 有效期,第一次遇到

4)檢查變量:p (printf)? 顯示表達式

x?? 顯示內存內容

5)監視點:watch 當監視點的值發生變化時停止

6)查看棧:bt(backtrace,where) 顯示整個棧的內容。

f(frame)選擇要顯示的棧幀

do(down) 在當前調用的棧幀中選擇要顯示的棧幀

7)看已經設的斷點: ib(info break)

8)設置斷點:break(b)

break function, break line_number, break filename:line_number, break filename:function

info break 查看斷點信息。

9)刪除斷點: d(delete),delete+數值標識符(從第7點可得到) (不加參數,刪除所有斷點), clear使用跟第8點對應

10)禁用斷點:disable+數值標識符 (重新啟用 enable)

11)在單步時跳出函數:finish

12)在單步時跳出循環:until

13)條件斷點:break break-arg if (condition),例: break main if argc > 1

14)斷點命令列表(到斷點自動執行):

commands breakpoint-number 例子:commands 1

... >printf "i = %d", i

commands >end

...

end

a) 在commands 中加入silent,過濾到其他無用的輸出。

b) 最后一個commands是continue的話,自動continue。

例:comands 1

> silent

> printf "i = %d", i

> continue

> end

15)查看局部變量:info locals 得到當前棧中所有局部變量的值列表

16)設置變量:set x=12

17)GDB線程命令:

a) info threads(給出當前所有的線程信息)

b) thread 3(切換查看線程)

c) break 88 thread 3(當線程3到達源代碼行88時停止執行)

d) break 88 thread 3 if x == y

e) thread apply all bt,查看所有的線程的棧信息。

18) 您可以以進程ID作為第二個參數,以調式一個正在運行的進程

gdb 程序名 1234

19)finish運行到函數結束

20)forward-search(或者fo)? 向前搜索

21)generate-core-file(或者gcore)? 生成內核轉儲

22edit 編輯文件或函數

23)directory(或者dir)插入目錄

24)list(或者l)顯示函數或者行

25)info (或者i)顯示信息

26)help (或者h)顯示幫助

注意

1)重新編譯文件時不要退出gdb,斷點可以保存著。

2)在調試時不要開啟優化代碼的選項,不然經過了優化,設置的斷點的位置跟編譯后的位置相差可能很大。


《深入理解計算機系統(原書第2版)》

更高級的GDB調試:

GDB attach到進程

總結

以上是生活随笔為你收集整理的GDB调试--以汇编语言为例的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。