I am taking a class for ARM processors, and we are doing some Assembly code. I am not asking for code to be written for me, but more of an file formatting question. The assignment is to create simple math code functions in a single file.
Part of the assignment states: Use the .global directive to define your function names and start your code with:
.global .section .text :
So my code is:
.global _start
_start:
mov r0, #-5
mov r1, #10
.global max
.section .text
max:
cmp r0, r1 //Compare r0 and r1
movlt r0, r1 // If r1 > r0, set r0 to r1
bx lr //return from function call
.global min
.section .text
min:
cmp r0, r1 // Compare r0 and r1
movgt r0, r1 // If r1 < r0, set r0 to r1
bx lr // Return from function call
.global abs
.section .text
abs:
cmp r0, #0 //Compare r0 and 0
rsblt r0, r0, #0 // if less than 0 then -r0
bx lr // Return from function call
Is this the proper way to put multiple functions in one assembly code file?
I've tried different ways like putting the function names inline .global _start with a comma between each like
.global _start, max, min, abs
and it compiles.
I also tried just having one .section .text and it also compiled.
I just don't know what the professor is asking for, and I may ask for clarification.
Thanks!
Yeah that looks correct. (Except for your _start
not ending with an _exit
system call, so execution will falling off into whatever's next, in this case max:
)
You don't need to keep switching to the .text
section before every function, though; the current section remains what you set until the next .section
directive or the end of the file. (And .text
is the default section at the top of the file, but it's good style to be explicit about that.) It doesn't do any harm, it's just distracting for the reader, especially since there isn't a .data
directive anywhere in your file (shorthand for .section .data
), since your functions only need code, no static constants or variables.
.text
, .data
, .bss
and .rodata
are the four main sections that compilers put stuff in. Changing sections means that's the part of the output where the assembler will assemble bytes into from later source lines, until you change again. .text
is read-only + exec, so that's the only good place to put machine code.
The assembler itself doesn't know or care about function boundaries, but it gives you the low-level building blocks to implement functions:
.global
so it's visible in the symbol-table of the .o
where the linker can see it.And yes you can do the exporting part with multiple operands to one .global
directive, although it's more usual to put stuff related to a symbol next to its label, so everything related to that function is in one block of lines you could move a to another file if you're re-factoring your source code.
(.global
is an alias for the .globl
directive. Some older assemblers, like Unix MIPS, only accept .globl
, so I tend to think of .globl
as the normal way and .global
as a compatibility alias, although the phrasing in the current GAS manual talks about .global
as the primary spelling and .globl
as the compatibility alias.)