參考資料:
《匯編語言程序設計》 Richard Blum 著
一. 編寫程序查看CPUID指令生成的廠商ID字符串
1 .section .data 2 output: 3 .ascii "The processor Vendor ID is 'xxxxxxxx'\n'" 4 .section .text 5 .globl _start 6 _start: 7 movl $0, %eax 8 cpuid 9 movl $output, %edi 10 movl %ebx, 28(%edi) 11 movl %edx, 32(%edi) 12 movl %ecx, 36(%edi) 13 movl $4, %eax 14 movl $1, %ebx 15 movl $output, %ecx 16 movl $42, %edx 17 int $0x80 18 movl $1, %eax 19 movl $0, %ebx 20 int $0x80
這部分代碼包含很多匯編指令, 具體的用法后面章節會細細道來, 今天主要是利用這個示例來講解整個匯編編譯,運行,鏈接,調試以及連接C庫函數
二. 下面對源碼如何工作的進行簡單講解:
首先, 在數據段聲明一個字符串
output: .ascii "The processor Vendor ID is 'xxxxxxxx'\n'"
.ascii聲明使用的是ASCII字符聲明一個文本字符串,字符串被預定義並放在內存中,起始位置由output指示
下面是程序模板的段落,聲明程序的指令碼段和一般的起始標簽:
.section .text
.globl _start
_start:
程序做的第一件事就是給EAX寄存器加載零值,然后運行CPUID指令:
movl $0, %eax
cpuid
EAX中的零值定義CPUID輸出選項(廠商ID),CPUID運行之后,必須收集分散在三個輸出寄存器中的指令響應
movl $output, %edi -> 創建一個指針聲明變量output,output內存加位置加載到EDI寄存器中
接下來按照EDI指針,包含廠商ID字符串的三個寄存器的內容被放到內存數據中的正確位置,括號外的數字表示相對於output標簽的放置數據的位置
數字和EDI寄存器中地址相加,就是值被寫入的地址
注意:廠商ID 字符串按照奇怪的EBX EDX 和 ECX分散存放
movl %ebx, 28(%edi)
movl %edx, 32(%edi)
movl %ecx, 36(%edi)
在內存中放置好廠商ID字符串之后,就可以顯示信息了:
movl $4, %eax
movl $1, %ebx
movl $output, %ecx
movl $42, %edx
int $0x80
使用系統調用(int $0x80)從linux 內核顯示到控制台
編譯鏈接:
as -o cpuid.o cpuid.s
ld -s -o cpuid cpuid.o
運行結果:The processor Vendor ID is 'GenuineIntel'
三. 調試程序
使用GDB,為了能夠調試匯編代碼,需要編譯時候添加-gstabs選項
as -gstabs -o cpuid.o cpuid.s
ld -s -o cpuid cpuid.o
3.1 單步運行
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1 Copyright (C) 2014 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 "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from cpuid...(no debugging symbols found)...done.
使用RUN指令運行
(gdb) run Starting program: /home/fly/smem-0.1/huibian/cpuid The processor Vendor ID is 'GenuineIntel.s[Inferior 1 (process 12863) exited normally]
基本調試命令與調試C類似,這里不做講解了
3.2 查看數據
info register: 顯示所有寄存器的值
print: 顯示特定寄存器或者程序變量的值
x: 顯示特定內存位置的內容
使用info reginster 查看指令如何影響所有寄存器是很方便的:
1 (gdb) info registers 2 rax 0x4 4 3 rbx 0x1 1 4 rcx 0x6000ec 6291692 5 rdx 0x2a 42 6 rsi 0x0 0 7 rdi 0x6000ec 6291692 8 rbp 0x0 0x0 9 rsp 0x7fffffffeb10 0x7fffffffeb10 10 r8 0x0 0 11 r9 0x0 0 12 r10 0x0 0 13 r11 0x200 512 14 r12 0x0 0 15 r13 0x0 0 16 r14 0x0 0 17 r15 0x0 0 18 rip 0x4000dc 0x4000dc <_start+44> 19 eflags 0x10202 [ IF RF ] 20 cs 0x33 51 21 ss 0x2b 43 22 ds 0x0 0 23 es 0x0 0 24 fs 0x0 0 25 gs 0x0 0