Jump to content

How do you run assembly code without an OS intervention?

Gat Pelsinger
Go to solution Solved by dcgreen2k,

The kind of programming you're talking about is called baremetal programming, since there's no OS providing resources, builtin functions, etc. for your code to use. There's a fair bit of setup you need to do before you can get even simple code running.

 

I'll note that I don't have much experience in this area, but you will have to define interrupt handlers + an interrupt descriptor table and implement functions for each syscall yourself. For the syscalls, you would write code that directly interfaces with hardware. (Example below)

Here are some useful links:

https://wiki.osdev.org/Interrupts

https://wiki.osdev.org/Interrupts_tutorial

https://filippo.io/linux-syscall-table/

 

Most of the tutorials on the OSDev Wiki require using both assembly and C. You will also need to create a simple kernel to get your code running, if you decide to go this route. Here's the tutorial for that: https://wiki.osdev.org/Bare_Bones

 

-----------

(Example)

Back when I was learning this kind of thing, I remember writing an implementation of puts() for my basic kernel's C library. All it did was print a string to the screen while in VGA text mode. To do this, you write characters directly into memory at address 0xB8000 which is the VGA text buffer. This is the lowest level of code needed to write characters to the screen, but after this you have a nice C function to use wherever you'd like.

I just kind of started learning x86 assembly, and there are stuff like interrupts and syscalls which need an OS to interpret, but what if I do not have an OS? Like look for C, all its function depend on the OS for carrying out certain function, but in assembly, I am literally writing barebones binary code that directly communicates with the CPU, but then there are still calls for the OS. If I wanted to make a program that runs without an OS, how would I replace my interrupts and syscalls?

 

Microsoft owns my soul.

 

Also, Dell is evil, but HP kinda nice.

Link to comment
Share on other sites

Link to post
Share on other sites

The kind of programming you're talking about is called baremetal programming, since there's no OS providing resources, builtin functions, etc. for your code to use. There's a fair bit of setup you need to do before you can get even simple code running.

 

I'll note that I don't have much experience in this area, but you will have to define interrupt handlers + an interrupt descriptor table and implement functions for each syscall yourself. For the syscalls, you would write code that directly interfaces with hardware. (Example below)

Here are some useful links:

https://wiki.osdev.org/Interrupts

https://wiki.osdev.org/Interrupts_tutorial

https://filippo.io/linux-syscall-table/

 

Most of the tutorials on the OSDev Wiki require using both assembly and C. You will also need to create a simple kernel to get your code running, if you decide to go this route. Here's the tutorial for that: https://wiki.osdev.org/Bare_Bones

 

-----------

(Example)

Back when I was learning this kind of thing, I remember writing an implementation of puts() for my basic kernel's C library. All it did was print a string to the screen while in VGA text mode. To do this, you write characters directly into memory at address 0xB8000 which is the VGA text buffer. This is the lowest level of code needed to write characters to the screen, but after this you have a nice C function to use wherever you'd like.

Computer engineering grad student, cybersecurity researcher, and hobbyist embedded systems developer

 

Daily Driver:

CPU: Ryzen 7 4800H | GPU: RTX 2060 | RAM: 16GB DDR4 3200MHz C16

 

Gaming PC:

CPU: Ryzen 5 5600X | GPU: EVGA RTX 2080Ti | RAM: 32GB DDR4 3200MHz C16

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, Gat Pelsinger said:

for C, all its function depend on the OS for carrying out certain function, but in assembly, I am literally writing barebones binary code that directly communicates with the CPU, but then there are still calls for the OS. If I wanted to make a program that runs without an OS, how would I replace my interrupts and syscalls?

The reason you "rely on the OS" is because you're using libraries for convenience. You could write everything stdlib/stdio/time/string etc. do by hand. It would simply be wasted effort to reinvent the wheel (most of the time).

 

C gets compiled into machine code, so it does exactly the same thing. The compiled binary directly runs on the CPU, directly modifies registers etc. It wouldn't be possible to use C to write a kernel otherwise (the Linux kernel for example is predominantly written in C). There is very little you can do in assembler you cannot also do in C (with some exceptions).

 

The other reason you can't do certain things is the operating system's/CPU's security model (ring 0 etc). You won't be able to circumvent that even when writing in assembler, unless you're writing your own kernel in which case you can get your code to run on ring 0.

Remember to either quote or @mention others, so they are notified of your reply

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, Gat Pelsinger said:

how would I replace my interrupts and syscalls?

You'll write them yourself.

 

There will be some BIOS routines you have access to as well.

 

 

F@H
Desktop: i9-13900K, ASUS Z790-E, 64GB DDR5-6000 CL36, RTX3080, 2TB MP600 Pro XT, 2TB SX8200Pro, 2x16TB Ironwolf RAID0, Corsair HX1200, Antec Vortex 360 AIO, Thermaltake Versa H25 TG, Samsung 4K curved 49" TV, 23" secondary, Mountain Everest Max

Mobile SFF rig: i9-9900K, Noctua NH-L9i, Asrock Z390 Phantom ITX-AC, 32GB, GTX1070, 2x1TB SX8200Pro RAID0, 2x5TB 2.5" HDD RAID0, Athena 500W Flex (Noctua fan), Custom 4.7l 3D printed case

 

Asus Zenbook UM325UA, Ryzen 7 5700u, 16GB, 1TB, OLED

 

GPD Win 2

Link to comment
Share on other sites

Link to post
Share on other sites

Also, here's some example code for baremetal x86 programs: https://github.com/cirosantilli/x86-bare-metal-examples

Computer engineering grad student, cybersecurity researcher, and hobbyist embedded systems developer

 

Daily Driver:

CPU: Ryzen 7 4800H | GPU: RTX 2060 | RAM: 16GB DDR4 3200MHz C16

 

Gaming PC:

CPU: Ryzen 5 5600X | GPU: EVGA RTX 2080Ti | RAM: 32GB DDR4 3200MHz C16

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×