Chinaunix首页 | 论坛 | 博客
  • 博客访问: 699002
  • 博文数量: 130
  • 博客积分: 2192
  • 博客等级: 大尉
  • 技术积分: 1410
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-31 15:37
文章分类

全部博文(130)

文章存档

2013年(1)

2012年(4)

2011年(27)

2010年(97)

2009年(1)

分类: 嵌入式

2010-08-01 22:14:47

3. 令人头疼的ARM汇编伪指令 .word

经常碰到那些以“.”打头的一些令人头疼的伪指令,

至于.globl _start  .balign .align .data .text等等就算了,最最bt的如下:

_undefined_instruction: .word undefined_instruction

这个.word令人费解。网上的技术人员都不屑回答,说请参考GNU ASM。我去看了,对于.word解释如下:

Syntax: .word expressions

This directive expects zero or more expressions, of any section, separated by commas. For each expression,
as emits a 16-bit number for this target.

以及as.info文档:

7.92 .word expressions

This directive expects zero or more expressions, of any section, separated by commas.

The size of the number emitted, and its byte order, depend on what target computer

the assembly is for.

Warning: Special Treatment to support Compilers

Machines with a 32-bit address space, but that do less than 32-bit addressing, require

the following special treatment. If the machine of interest to you does 32-bit addressing

(or doesn’t require it; see Chapter 8 [Machine Dependencies], page 61), you can ignore this

issue.

In order to assemble compiler output into something that works, as occasionally does

strange things to ‘.word’ directives. Directives of the form ‘.word sym1-sym2’ are often

emitted by compilers as part of jump tables. Therefore, when as assembles a directive of

the form ‘.word sym1-sym2’, and the difference between sym1 and sym2 does not fit in 16

bits, as creates a secondary jump table, immediately before the next label. This secondary

jump table is preceded by a short-jump to the first byte after the secondary table. This

short-jump prevents the flow of control from accidentally falling into the new table. Inside

the table is a long-jump to sym2. The original ‘.word’ contains sym1 minus the address of

the long-jump to sym2.

If there were several occurrences of ‘.word sym1-sym2’ before the secondary jump table,

all of them are adjusted. If there was a ‘.word sym3-sym4’, that also did not fit in sixteen

bits, a long-jump to sym4 is included in the secondary jump table, and the .word directives

are adjusted to contain sym3 minus the address of the long-jump to sym4; and so on, for as

many entries in the original jump table as necessary.

 

看了以后仍然一头雾水。

我把bin文件反汇编,想通过这种方法来找找这个.word究竟干什么。

原汇编程序:(start.S)

.globl _start

_start:     b       reset

       ldr   pc, _undefined_instruction

       ldr   pc, _software_interrupt

       ldr   pc, _prefetch_abort

       ldr   pc, _data_abort

       ldr   pc, _not_used

       ldr   pc, _irq

       ldr   pc, _fiq

 

_undefined_instruction:  .word undefined_instruction

_software_interrupt:      .word software_interrupt

_prefetch_abort:     .word prefetch_abort

_data_abort:           .word data_abort

_not_used:             .word not_used

_irq:               .word irq

_fiq:               .word fiq

 

       .balignl 16,0xdeadbeef

 

_TEXT_BASE:

       .word      TEXT_BASE

 

.globl _armboot_start

_armboot_start:

       .word _start

 

.globl _bss_start

_bss_start:

       .word __bss_start

 

.globl _bss_end

_bss_end:

       .word _end

 

reset:

       /*

        * set the cpu to SVC32 mode

        */

       mrs  r0,cpsr

       bic   r0,r0,#0x1f

       orr   r0,r0,#0xd3

       msr  cpsr,r0

 

对应的反汇编:

00000000       [0xea000012]   b        0x50

00000004       [0xe59ff014]   ldr      pc,0x00000020 ; = #0x33f80140

00000008       [0xe59ff014]   ldr      pc,0x00000024 ; = #0x33f801a0

0000000c      [0xe59ff014]   ldr      pc,0x00000028 ; = #0x33f80200

00000010       [0xe59ff014]   ldr      pc,0x0000002c ; = #0x33f80260

00000014       [0xe59ff014]   ldr      pc,0x00000030 ; = #0x33f802c0

00000018       [0xe59ff014]   ldr      pc,0x00000034 ; = #0x33f80320

0000001c      [0xe59ff014]   ldr      pc,0x00000038 ; = #0x33f80380

00000020       [0x33f80140]   mvnccs   r0,#0x10 ; ? rn = 0x8

00000024       [0x33f801a0]   mvnccs   r0,#0x28 ; ? rn = 0x8

00000028       [0x33f80200]   mvnccs   r0,#0, 4 ; ? rn = 0x8

0000002c           [0x33f80260]   mvnccs   r0,#6 ; ? rn = 0x8

00000030       [0x33f802c0]   mvnccs   r0,#0xc ; ? rn = 0x8

00000034       [0x33f80320]   mvnccs   r0,#0x80000000 ; ? rn = 0x8

00000038       [0x33f80380]   mvnccs   r0,#2 ; ? rn = 0x8

0000003c      [0xdeadbeef]   cdple    p14,0xa,c11,c13,c15,7

00000040       [0x33f80000]   mvnccs   r0,#0 ; ? rn = 0x8

00000044       [0x33f80000]   mvnccs   r0,#0 ; ? rn = 0x8

00000048       [0x33f96650]   mvnccs   r6,#0x5000000 ; ? rn = 0x9

0000004c      [0x33f9ab80]   mvnccs   r10,#0x20000 ; ? rn = 0x9

00000050       [0xe10f0000]   mrs      r0,cpsr

00000054       [0xe3c0001f]   bic      r0,r0,#0x1f

00000058       [0xe38000d3]   orr      r0,r0,#0xd3

0000005c      [0xe129f000]   msr      cpsr_cf,r0

 

 

这么看来,

_undefined_instruction:  .word undefined_instruction

这句对应的反汇编是:
mvnccs r0,#0x10 ;

这么一来我又更糊涂了。

 

ChinaUnix求助。幸好碰到一位热心的网友wheelz,详细地给我解答了。

帖子链接如下:

 

现在总结wheelz的回答,说说这个.word的作用。

 

word expression就是在当前位置放一个word型的值,这个值就是expression
举例来说,

_rWTCON:
.word 0x15300000
就是在当前地址,即_rWTCON处放一个值
0x15300000

翻译成intel的汇编语句就是:

_rWTCON dw 0x15300000

 

就是在当前位置放个expression的值。 原来如此啊。

 

PS:

贴一个##的作用。

#define _syscall0(type,name) \
type name(void) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \
 : "=a" (__res) \
 : "0" (__NR_##name)); \
if (__res >= 0) \
 return (type) __res; \
errno = -__res; \
return -1; \
}

__NR_##name是系统调用号,##指的是两次宏展开.即用实际的系统调用名字代替"name",然后再把__NR_...展开.如name == ioctl,则为__NR_ioctl
阅读(3571) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~