1. 程式人生 > >ARM彙編偽指令 .word

ARM彙編偽指令 .word

ARM彙編偽指令 .word 

經常碰到那些以“.”打頭的一些令人頭疼的偽指令, 
至於.globl _start .balign .align .data .text等等就算了,最最bt的如下: 

_undefined_instruction: .word undefined_instruction 

這個.word令人費解。網上的技術人員都不屑回答,說請參考GNU ASM。我去看了,對於.word解釋如下: 

[url=http://tigcc.ticalc.org/doc/gnuasm.html#SEC49]http://tigcc.ticalc.org/doc/gnuasm.html#SEC49 

.word 
Syntax: .word expressions  

Thisdirective expects zero or more expressions, of any section, separatedby commas. For each expression, as emits a 16-bit number for thistarget. 

以及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,詳細地給我解答了。 
帖子連結如下: 
[url=http://www.linuxforum.net/forum/showflat.php?Cat=&Board=linuxK&Number=563178]http://www.linuxforum.net/forum/showflat.p…K&Number=563178 

現在總結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。

 

轉自https://blog.csdn.net/qq_33396481/article/details/78953583