您好,欢迎来到 - 67学习网 - http://www.67xuexi.com !

Linux下的AT&T语法

摘要:AT&T 处理操作数的顺序和Intel相反,比如,movl %eax, %ebx是将eax中的值传递给ebx,而Intel是这样的mov ebx, eaxAT&T在助记符的后面加上一个单独字符表示操作中数据的长度,比如movl $foo, %eax等同于Intel的mov eax, word ptr foo长跳转和调用的格式不同,AT&T为ljmp $section, $offset,而Intel为jmp section:offset主要的区别就是这些,其他的细节还有很多,下面给出一个具体的例子来说明#cpuid.s Sample program.section .dataoutput:.ascii "The processor Vendor ID is 'xxxxxxxxxxxx'n".section .text.globl _start_start:movl $0, %eaxcpuidmovl $output, %edimovl %ebx, 28(%edi)movl %edx, 32(%edi)movl %ecx, 36(
Linux下的AT&T语法,标签:服务器,操作系统教程大全,http://www.67xuexi.com

  AT&T 处理操作数的顺序和Intel相反,比如,movl %eax, %ebx是将eax中的值传递给ebx,而Intel是这样的mov ebx, eax

  AT&T在助记符的后面加上一个单独字符表示操作中数据的长度,比如movl $foo, %eax等同于Intel的mov eax, word ptr foo

  长跳转和调用的格式不同,AT&T为ljmp $section, $offset,而Intel为jmp section:offset

  主要的区别就是这些,其他的细节还有很多,下面给出一个具体的例子来说明

  #cpuid.s Sample program

  .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

  这个程序的作用是查询CPU的厂商ID,其中:

  ,ascii定义字符串(和Intel格式完全不同).section是声明段的语句,.data和.text是段名,分别为数据段和代码段, _start是gas(GNU汇编器)的默认入口标签,表示程序从这里开始执行。.globl将_start声明成了外部程序访问的标签。cpuid为指令请求CPU的指定信息,该指令用eax作为输入,ebx,edx,ecx作为输出,这里将0作为cpuid的输入指令,请求返回CPU的厂商ID字符串。返回的结果,一个12字节的字符串,分别存储在三个寄存器中,其中ebx存放低4位,edx中间4位,ecx高4位(注意顺序!)。接下来定义一个指针edi,edi指向output的开始地址,然后接着的3条语句将output里的x替换为厂商信息。28(%edi)中的28表示偏移量,即整个地址为%edi里的地址加上28个字节,这个地址正好是output里第一个x的地址。再接下来就是打印结果了,这里用到了Linux的一个系统调用(int 0x80),该系统调用的参数分别为:eax 系统调用号,ebx 要写入的文件描述符,ecx 字符串首地址,edx 字符串长度,程序里这些个参数的值分别为4,1(标准输出),output的地址和42。最后再次调用1号系统调用-退出函数,返回shell,这次 ebx中的值是返回给shell的退出代码,0表示无异常

  然后汇编连接运行程序:

  [root@zieckey-laptop src]# as -o cpuid.o cpuid.s

  [root@zieckey-laptop src]# ld cpuid.o -o cpuid

  [root@zieckey-laptop src]# ./cpuid

  The processor Vendor ID is 'GenuineIntel'

  [root@zieckey-laptop src]#

  本人的电脑是Pentium M的CPU所以返回的结果是GenuineIntel。

  几点说明:

  1)Linux的标准汇编环境为as,ld,gdb,gprof,objdump等GNU开发调试工具,除了gdb外,其他全部随binutils包发布。其中as使用的是AT&T语法。在Linux下也可以使用Nasm来进行Intel格式的汇编程序编写

  2)Linux下汇编的系统调用为int 0x80,和DOS下的int 21h大同小异,只不过传递参数不同

  3)段声明语句.section不需要像Intel格式那样在段结尾的时候加上段结束标志(SEGMENT/ENDS),下一个段的开始自动标志着上个段的结束

  4)简单程序的入口标签不是必须要定义的,ld会自己判断入口,但是会给出警告

  ===========================================例子2

  例 2. 求一组数的最大值的汇编程序#PURPOSE: This program finds the maximum number of a

  # set of data items.

  #

  #VARIABLES: The registers have the following uses:

  #

  # %edi - Holds the index of the data item being examined

  # %ebx - Largest data item found

  # %eax - Current data item

  #

  # The following memory locations are used:

  #

  # data_items - contains the item data. A 0 is used

  # to terminate the data

  #

  .section .data

  data_items: #These are the data items

  .long 3,67,34,222,45,75,54,34,44,33,22,11,66,0

  .section .text

  .globl _start

  _start:

  movl $0, %edi # move 0 into the index register

  movl data_items(,%edi,4), %eax # load the first byte of data

  movl %eax, %ebx # since this is the first item, %eax is

  # the biggest

  start_loop: # start loop

  cmpl $0, %eax # check to see if we've hit the end

  je loop_exit

  incl %edi # load next value

  movl data_items(,%edi,4), %eax

  cmpl %ebx, %eax # compare values

  jle start_loop # jump to loop beginning if the new

  # one isn't bigger

  movl %eax, %ebx # move the value as the largest

  jmp start_loop # jump to loop beginning

  loop_exit:

  # %ebx is the status code for the exit system call

  # and it already has the maximum number

  movl $1, %eax #1 is the exit() syscall

  int $0x80

  汇编、链接、执行:

  $ as max.s -o max.o

  $ ld max.o -o max

  $ ./max

  $ echo $?

  这个程序在一组数中找到一个最大的数,并把它作为程序的退出状态。这组数在.data段给出:

  data_items:

  .long 3,67,34,222,45,75,54,34,44,33,22,11,66,0

  .long指示声明一组数,每个数占32位,相当于C语言中的数组。这个数组开头有一个标号data_items,汇编器会把数组的首地址作为data_items符号所代表的地址,data_items类似于C语言中的数组名。data_items这个标号没有用.globl声明,因为它只在这个汇编程序内部使用,链接器不需要知道这个名字的存在。除了.long之外,常用的数据声明还有:

上一页  [1] [2] [3]  下一页


Tag:服务器_操作系统教程服务器,操作系统教程大全电脑教程 - 服务器_操作系统教程