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.
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
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.
.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:
.globalso it's visible in the symbol-table of the
.owhere 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.)