MOP2 programming intro - add printing in C and error codes
This commit is contained in:
@ -55,8 +55,6 @@ writing something to a pipe.
|
|||||||
|
|
||||||
STRING:
|
STRING:
|
||||||
.string "Hello world!!!"
|
.string "Hello world!!!"
|
||||||
STRING_LEN:
|
|
||||||
.quad . - STRING
|
|
||||||
|
|
||||||
.section .text
|
.section .text
|
||||||
|
|
||||||
@ -64,7 +62,6 @@ STRING_LEN:
|
|||||||
_start:
|
_start:
|
||||||
movq $1, %rax // select debugprint()
|
movq $1, %rax // select debugprint()
|
||||||
lea STRING(%rip), %rdi // load STRING
|
lea STRING(%rip), %rdi // load STRING
|
||||||
lea STRING_LEN(%rip), %rsi // load STRING_LEN
|
|
||||||
int $0x80
|
int $0x80
|
||||||
|
|
||||||
// quit
|
// quit
|
||||||
@ -187,3 +184,62 @@ limitation of this approach is that the caller must ensure that enough space wit
|
|||||||
problematic in the future.
|
problematic in the future.
|
||||||
|
|
||||||
After we've exited from `main()`, we just gracefully exit the application.
|
After we've exited from `main()`, we just gracefully exit the application.
|
||||||
|
|
||||||
|
=== "Hello world" but from C this time
|
||||||
|
|
||||||
|
Now we can program our applications the "normal"/"human" way. We've gone over printing in assembly using the
|
||||||
|
`debugprint()` syscall, so let's now try to use it from C. We'll also try to do some more advanced printing
|
||||||
|
with (spoiler) `uprintf()`.
|
||||||
|
|
||||||
|
.Calling `debugprint()` from C
|
||||||
|
[source,c]
|
||||||
|
----
|
||||||
|
// Import `ulib`
|
||||||
|
#include <ulib.h>
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
debugprint("hello world");
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
That's it! We've just printed "hello world" to the terminal! How awesome is that?
|
||||||
|
|
||||||
|
.`uprintf()` and formatted printing
|
||||||
|
[source,c]
|
||||||
|
----
|
||||||
|
#include <ulib.h>
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
uprintf("Hello world %d %s %02X\n", 123, "this is a string literal", 0xBE);
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
`uprintf()` is provided by Eyal Rozenberg (eyalroz), which originates from Macro Paland's printf. This printf
|
||||||
|
library is super easily portable and doesn't require much in terms of standard C functions and headers. My main
|
||||||
|
nitpick and a dealbreaker with other libraries was that they advertise themsevles as "freestanding" or "made for
|
||||||
|
embedded" or something along those lines, but in reality they need so much of the C standard library, that you
|
||||||
|
migh as well link with musl or glibc and use printf from there. And generally speaking, this is an issue with
|
||||||
|
quite a bit of "freestanding" libraries that you can find online ;(.
|
||||||
|
|
||||||
|
Printf rant over...
|
||||||
|
|
||||||
|
=== Error codes in MOP2
|
||||||
|
|
||||||
|
You might've noticed is that `main()` looks a little different from standard C `main()`. There's
|
||||||
|
no return/error code, because MOP2 simply does not implement such feature. This is because MOP2 doesn't follow the
|
||||||
|
UNIX philosophy.
|
||||||
|
|
||||||
|
The UNIX workflow consists of combining many small/tiny programs into a one big commandline, which transforms text
|
||||||
|
into some more text. For eg.:
|
||||||
|
|
||||||
|
.Example bash command (Linux) to get a name of /proc/meminfo field
|
||||||
|
[source,shell]
|
||||||
|
----
|
||||||
|
cat /proc/meminfo | awk 'NR==20 {print $1}' | rev | cut -c 2- | rev
|
||||||
|
----
|
||||||
|
|
||||||
|
Personally, I dislike this type of workflow. I prefer to have a few programs that perform tasks groupped by topic,
|
||||||
|
so for eg. in MOP2, we have `$fs` for working with the filesystem or `$pctl` for working with processes. When we
|
||||||
|
approach things the MOP2 way, it turns out error codes are kind of useless (or at least they wouldn't get much
|
||||||
|
use), since we don't need to connect many programs together to get something done.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user