Chinaunix首页 | 论坛 | 博客
  • 博客访问: 179368
  • 博文数量: 69
  • 博客积分: 2627
  • 博客等级: 少校
  • 技术积分: 715
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-24 22:37
文章分类

全部博文(69)

文章存档

2017年(3)

2014年(1)

2013年(4)

2012年(6)

2011年(21)

2010年(15)

2009年(19)

我的朋友

分类: LINUX

2009-04-09 22:11:50

第四章 A Sample Assembly Language Program
three secitons:
  . the data section
  . the bss  section
  . the text section

text必须,它是指令代码
data是有初始值的数据部分,在汇编程序做为变量用
bss部分用0或null初始化,通常作为汇编程的缓冲区


Defining sections
.section指令带一个参数.

常用形式
.section .data
.section .bss
.section .text

Defining the starting point
当汇编程序转换成可执行文件,连接器必须知道指令代码的开始点.
GNU汇编器声明了一个默认的标签,或标识符,用于应用程序的入口点.

_start标签用于表示从哪个程序开始执行.
如果连接器找不到这个标签,它会产生一个错误:
ld: warning: cannot find entry symbol _start; defaulting to 08048074
如果连接器找不到_start,它会试着找程序的开头,但对于复杂的程序,不能保证
它能猜对。
  注意:除了使用_start,还可以用-e参数

除了定义_start,还要保证它可能使用,这要用到.globl指令

汇编模板:
.section .data
    < initialized data here>
.section .bss
    < uninitialized data here>
.section .text
.globl _start
_start:
    

Create a sample assemply program
CPUID指令:一个不容易从高级语言程序运行的指令.
它是一个查询处理器特定信息的低级指令,并在特定寄存器保存返回的信息.
它使用单寄存器EAX值作为输入.EAX用来确定CPUID指令将产生的信息.
根据EAX,CPUID将在EBX,ECX,EDX产生关于处理器的不同信息.
返回的信息作为一串位值和标志,它必须被适当解析。

例子使用0选项取出厂商字符串.CPUID执行后,处理器返回厂商ID字符串在ebx,edx,和ECX如下:
  .EBX包含字串前4字节
  .EDX包含字串中间4字节
  .ECX包含字串最后4字节, 以小端格式存放,

用CPUID前最好测试这个指令是否能用,示例程序没有测试:


The Sample Program
#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:
    mov $0,%eax
    cpuid
    movl $output,%edi
    movl %ebx,28(%edi)    # place vendor id string in xxxxxxxxxx
    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

.ascii指令用来声明一个ASCII字符串,起始位置由outpu来指定. xxx...用来占位的。

下面把0放入EAX,然后运行CPUID。
movl $0,%eax
cpuid


12章将讲解linux系统调用.
系统调用1, 是exit函数


Building the executable
as -o cpuid.o cpuid.s
ld -o cpuid cpuid.o


Running the executable
# ./cpuid
The processor Vendor ID is 'GenuineIntel'


Assembling using a compiler
使用gcc汇编程序有个问题。GNU连接器找_start标签,gcc找main标签,所以要把_start,变成main
.section .text
.globl main
main:

# gcc -o cpuid cpuid.s


Debugging the program
使用GDB调试,要重新汇编源代码,加上-gstabs选项
# as -gstabs -o cpuid.o cpuid.s
# ld -o cpuid cpuid.o

断点的设置:
  . 标签
  . 源代码的行号
  . 当到达一个指定的数据值
  . 一个执行了特定次数的函数

设置断点:
 break *label + offset
label:程序引用的标签, offset是从标签开始起.

阅读(614) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~