0

I'm currently trying to get into OS development, mostly following the articles and tutorials from OSDev. As os now, I have multiple assembly files I need to e.g. enable paging and setting up long mode.

While the only assembler code I'm certain about needs to be separated in an own file is the boot assembly file, I'm curious about the practices and "standards" how to deal with assembly in an OS written in C. Is it convenient to separate assembler from C or is there a reason why e.g. Linux wraps most of the assembly code inside C functions and calls them using the asm volatile directives?

I don't see much difference, as you can return results from assembly by moving the value into the eax register, or when using asm and asm volatile, you can specify parameters and output operands where to store the result. However, you always need to separate multiple instructions by using \n or \n\t.

As of now, I only found out about the different ways of dealing with assembly in a larger project, but not why some chose to separate assembly code from C or C++, and why some chose to use inline assembly thorough the whole program.

I hope you could give me some insights about the different ways used regarding this topic.

CRoemheld
  • 889
  • 7
  • 26
  • *you can return results from assembly by moving the value into the eax register*. That might appear to work, but only works by accident. You can't use GNU C inline asm safely unless you use input and output operands to tell the compiler what you're doing. It will break when the compiler inlines your function into a caller. See [this answer](https://stackoverflow.com/questions/34520013/using-base-pointer-register-in-c-inline-asm) for some more links about inline asm, and the kind of trouble you can get into from using it wrong. – Peter Cordes May 23 '18 at 18:59

1 Answers1

2

Interface, Procotol & Conventions

In a pure assembly language project, you need to set up protocols or conventions for passing values and returning values.

When mixing assembly language functions with C or C++, you will need to follow the parameter passing conventions of C or C++ as dictated by the compiler you are using.

Some compilers may use a convention of passing the first parameter in R0, while others may pass the last parameter in R0. Some compilers may place the variables on the stack and not use registers. Others may use registers for a few parameters and the remaining on the stack.

Inline vs Separate Assembly functions

One issue is portability. Assembly language is processor specific. For example, ARM assembly doesn't have an EAX register. Intel assembly doesn't have R10 register. When using inline assembly, the assembly must change depending on the processor, which includes modifying the high level language function to account for all target processors. When implementing as a separate assembly function (file), only the file needs to be swapped out when porting to other processors.

IMHO, pure assembly functions are easier to read than intermixed C and inline assembly.

Guidelines for High Level Language Usage in OS

The quantity of assembly language should be minimized. Assembly language takes longer to develop (typing, and debugging, more lines == high possible injected defects), whereas the high level language is more productive with lower risks.

Prefer to write the entire OS in a high level language. Get this version working robustly. Replace C functions with assembly functions for more efficiency, or when specific assembly language instructions are required.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
  • This sounds reasonable. Also, writing more in a high level language should also circumvent the problem regarding assembly, since the compiler translates a program/file to the architecture the compiler is targeting. So only some (few) parts of the OS should be written in assembly, if there is no C-equivalent code or if you need to manipulate some specific register for the OS? – CRoemheld May 23 '18 at 21:41
  • Inline asm can be... well, inlined, whereas a call to an asm routine must always incur the cost of the call/ret, so there's that. But mostly I'm of the opinion that [you should not use inline asm](https://gcc.gnu.org/wiki/DontUseInlineAsm). – David Wohlferd May 24 '18 at 02:46