《汇编语言》--程序范例

参考资料:

《汇编语言程序设计》 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
posted @ 2019-06-20 00:40  坚持,每天进步一点点  阅读(1837)  评论(0编辑  收藏  举报