注:以下内容为学习笔记,多数是从书本、资料中得来,只为加深印象,及日后参考。然而本人表达能力较差,写的不好。因非翻译、非转载,只好选原创,但多数乃摘抄,实为惭愧。但若能帮助一二访客,幸甚!
调试在编程中是不可缺少的,尝试使用GDB 调试一下昨晚的AT&T汇编代码:
- liury@liury-laptop:~/program/asm/cpuid$ as -gstabs -o cpuid.o cpuid.s
- liury@liury-laptop:~/program/asm/cpuid$ ls
- cpuid.o cpuid.s cpuid.s~ makefile makefile~
- liury@liury-laptop:~/program/asm/cpuid$ ld -o cpuid cpuid.o
- liury@liury-laptop:~/program/asm/cpuid$ gdb cpuid
- GNU gdb (GDB) 7.1-ubuntu
- Copyright (C) 2010 Free Software Foundation, Inc.
- License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
- This is free software: you are free to change and redistribute it.
- There is NO WARRANTY, to the extent permitted by law. Type "show copying"
- and "show warranty" for details.
- This GDB was configured as "i486-linux-gnu".
- For bug reporting instructions, please see:
- <http://www.gnu.org/software/gdb/bugs/>...
- Reading symbols from /home/liury/program/asm/cpuid/cpuid...done.
- (gdb) l
- 1 # cpuid.s Sample program to extract the processor Vendor ID
- 2 .section .data
- 3 output:
- 4 .ascii "The processor Vendor ID is 'XXXXXXXXXXXX'\n"
- 5
- 6 .section .text
- 7 .global _start
- 8
- 9 _start:
- 10 movl $0, %eax # The CPUID output option(the Vendor ID string)
- (gdb) break *_start
- Breakpoint 1 at 0x8048074: file cpuid.s, line 10.
- (gdb) r
- Starting program: /home/liury/program/asm/cpuid/cpuid
- The processor Vendor ID is 'GenuineIntel'
- Program exited normally.
- (gdb) q
发现断点处没有停,后来得知此乃GDB的一个BUG...而必须在_start后面的第一个指令码元素的位置包含一条伪指令。
需要在_start后面加一条NOP指令:
- _start:
- nop
- movl $0, %eax
- cpuid
- liury@liury-laptop:~/program/asm/cpuid$ gdb cpuid
- GNU gdb (GDB) 7.1-ubuntu
- Copyright (C) 2010 Free Software Foundation, Inc.
- License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
- This is free software: you are free to change and redistribute it.
- There is NO WARRANTY, to the extent permitted by law. Type "show copying"
- and "show warranty" for details.
- This GDB was configured as "i486-linux-gnu".
- For bug reporting instructions, please see:
- <http://www.gnu.org/software/gdb/bugs/>...
- Reading symbols from /home/liury/program/asm/cpuid/cpuid...done.
- (gdb) l
- 1 # cpuid.s Sample program to extract the processor Vendor ID
- 2 .section .data
- 3 output:
- 4 .ascii "The processor Vendor ID is 'XXXXXXXXXXXX'\n"
- 5
- 6 .section .text
- 7 .global _start
- 8
- 9 _start:
- 10 nop
- (gdb) break *_start+1
- Breakpoint 1 at 0x8048075: file cpuid.s, line 11.
- (gdb) r
- Starting program: /home/liury/program/asm/cpuid/cpuid
- Breakpoint 1, _start () at cpuid.s:11
- 11 movl $0, %eax # The CPUID output option(the Vendor ID string)
- (gdb) next
- 12 cpuid
- (gdb) info registers
- eax 0x0 0
- ecx 0x0 0
- edx 0x0 0
- ebx 0x0 0
- esp 0xbffff0a0 0xbffff0a0
- ebp 0x0 0x0
- esi 0x0 0
- edi 0x0 0
- eip 0x804807a 0x804807a <_start+6>
- eflags 0x212 [ AF IF ]
- cs 0x73 115
- ss 0x7b 123
- ds 0x7b 123
- es 0x7b 123
- fs 0x0 0
- gs 0x0 0
- (gdb) n
- 13 movl $output,%edi
- (gdb) info registers
- eax 0xa 10
- ecx 0x6c65746e 1818588270
- edx 0x49656e69 1231384169
- ebx 0x756e6547 1970169159
- esp 0xbffff0a0 0xbffff0a0
- ebp 0x0 0x0
- esi 0x0 0
- edi 0x0 0
- eip 0x804807c 0x804807c <_start+8>
- eflags 0x212 [ AF IF ]
- cs 0x73 115
- ss 0x7b 123
- ds 0x7b 123
- es 0x7b 123
- fs 0x0 0
- gs 0x0 0
- (gdb) print /x $ecx
- $1 = 0x6c65746e
- (gdb) x /42cb &output
- 0x80490ac <output>: 84 'T' 104 'h' 101 'e' 32 ' ' 112 'p' 114 'r' 111 'o' 99 'c'
- 0x80490b4 <output+8>: 101 'e' 115 's' 115 's' 111 'o' 114 'r' 32 ' ' 86 'V' 101 'e'
- 0x80490bc <output+16>: 110 'n' 100 'd' 111 'o' 114 'r' 32 ' ' 73 'I' 68 'D' 32 ' '
- 0x80490c4 <output+24>: 105 'i' 115 's' 32 ' ' 39 '\'' 88 'X' 88 'X' 88 'X' 88 'X'
- 0x80490cc <output+32>: 88 'X' 88 'X' 88 'X' 88 'X' 88 'X' 88 'X' 88 'X' 88 'X'
- 0x80490d4 <output+40>: 39 '\'' 10 '\n'
- (gdb) c
- Continuing.
- The processor Vendor ID is 'GenuineIntel'
- Program exited normally.
- (gdb) q
注释:
break 加断点
run 运行
next 单步运行
info registers 显示所有寄存器的值
print 显示特定寄存器的值
print /d 显示十进制的值
print /t 显示二进制的值
print /x 显示十六进制的值
x 显示特定内存地址的内容
x /nyz
n是要显示的字段数,y是输出格式:
c 用于字符
d 十进制
x 十六进制
z是要显示的字段长度
b 字节8位
h 16位
w 32位字
q 退出gdb