I'm trying to learn ARM assembly.
After writing this small Hello World program:
.global _start
.text
_start: ldr R1,=msgtxt
mov R2,#13
mov R0,#1
mov R7,#4
svc 0
mov R7,#1
svc 0
.data
msgtxt: .ascii "Hello World!\n"
.end
I noticed I could remove the .text and .data directive, the program would work just as well.
I'm therefore curious : everything I read emphasized the fact that .text section is to be used for code and .data for data. But here, before my eyes, they seem to do nothing at all!
Therefore, if these are not used to hold code and data respectively, what is their true purpose?
GAS (like most assemblers) defaults to the .text
section, and your read-only data still works in .text
You can do echo 'mov r1, #2' > foo.s
and assemble+link that into an ARM binary (with
gcc -nostdlib -static foo.s
for example). You can single-step that instruction in GDB.
(Without a sys_exit
system call your program will crash after that, but of course you could do that too still without any directives.)
The linker will warn that it didn't find a _start
symbol (because you left out the label itself, not to mention the .globl
directive that told the assembler to make it visible in the object file's symbol table.
But GNU binutils ld
's default is to use the start of the .text
section as the ELF entry point.
Most sections other than .text
aren't linked into executable memory by default, so having _start:
in .data
would normally be a problem.
Read-only data should normally go in the .rodata
section, which is linked as part of the TEXT segment anyway. So as far as runtime behaviour is concerned, placing it at the end of the .text
section (by leaving out .data
) is pretty much exactly equivalent to what you should have done.
What's the difference of section and segment in ELF file format
Putting it in .data
leads to the linker putting it in a different segment that tells the OS's ELF program loader to map it read+write (and not execute).
The point of having a .rodata
section separate from .text
is to group code together and data together. Many CPUs have split L1d and L1i caches, and/or separate TLBs for data / instructions, so fine-grained mixing of read-only data with code wastes space in split caches.
In your case, you're not linking any other file that also have some code and some data, so there's no difference.