0

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!

5
  • As Peter says, you can relax much of that boilerplate. Once your in .text, no need to say it again; .global/.globl often allows multiple identifiers. But it is up to you as to what style you want to have in your source code. Commented Sep 29, 2023 at 0:13
  • just like in other programming languages more than one function per file is perfectly fine. Commented Sep 29, 2023 at 2:42
  • this looks like gnu assembler or maybe clang? yes? the file starts off in .text section mode you arguably do not even have to state it. as stated above though one at the top is enough. if you are going to declare .text then you should do it before any instructions (before those mov instructions after start) Commented Sep 29, 2023 at 2:43
  • it is not possible for us to know what the professor thinks is correct. other than those mov statements at the top not being covered, explicitly, by a .text it is perfectly fine, but our opinion of fine may be a fail in the eyes of your professsor. so ask the professor and do it the professors way for the duration of the class then find your own style as there are many valid ways, there is no one correct way, there is a very long list of correct ways. Commented Sep 29, 2023 at 2:46
  • actually those two instructions out front are out of place, are they there for a reason, do you want a return or branch to self or something there or...if you execute them then you fall into max and then crash on the bx lr. Commented Sep 29, 2023 at 2:48

1 Answer 1

1

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:

  • define a symbol via a label
  • mark it as exported it with .global so it's visible in the symbol-table of the .o where the linker can see it.
  • assemble some bytes of machine code starting at the address the symbol is attached to, so if some other code jumps here, that code will run.

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.)

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the excellent answer and guidance!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.