views:

78

answers:

2

Okay, so I understand all of us C/C++ programmers have at one time met our untimely nemesis, the diabolical signal SIGSEGV, the Segmentation Fault. Now, I understood (emphasis on the past tense) this to be some form of fail safe / checking system within some portion of the machine code spat out by the magical GCC (or g++) compiler, or what have you.

But! Today I was screwing around with some x86 assembler with good old NASM on a virtualized Arch Linux system, and much to my surprise and chagrin, was once again thwarted in my coding efforts by the nefarious SegFault.

Here is the code that spawned the dreaded signal:

mov eax, 0x7
mov [0xB8000], eax

Now, I understand that the Linux kernel loads your assembled program into a shell and executes it from there, but I thought this MOV instruction interacted 1 to 1 with the processor, how on Earth can the Kernel detect that I'm trying to access a bit of memory it doesn't want me to, and halt the instruction?

I don't pretend to understand what exactly happens when your program is loaded into a shell, what permissions you have once in the shell, or even what a shell is or how it works, but I used to be dang sure that ASM gave you full control over the processor. How does this magical Kernel interfere with my direct commands to the processor, and why am I still forced to go through this chain of Operating System command when writing, essentially, pure machine code? :O

+3  A: 

The MMU has protected the memory you're trying to access, so when you execute an instruction that violates some permissions, an interrupt/processor exception is generated. That exception is handled by the kernel and forwarded to your application as a segmentation fault signal. Since your application doesn't handle SIGSEGV, it is terminated, and control returned to your shell.

If you want the "full control over the processor" you're looking for, you'll need to write code at a lower level (in the kernel if you want to keep the OS running, or your own OS or executive if you want to handle everything from boot yourself).

Writing an assembly program is no different from writing a C program, except that maybe you can generate some weird instructions your C compiler wouldn't emit. There are no special permissions or abilities granted to a program just based on the language in which it is written.

Carl Norum
Huh, your explanation and a quick Wikipedia search of MMU was very enlightening, I'm too used to doing assembly for z80 and 6502 processors for recreation, I never knew separate units existed for handling memory and protecting it. I had some vague knowledge of memory mapped I/O (if that's even related), but for something like memory management to be implemented in hardware on todays systems is really interesting.
N8-bit
@N8-bit, memory-mapped I/O is also some hardware magic, but it's not necessarily MMU-related.
Carl Norum
MMUs are no longer separate units as they often were 20-30 years ago. They are integrated into the CPU now, just as floating-point units are.
Gabe
@Gabe is quite correct; in general all these parts are in the same package, but often have signs of their origins as external parts in the way they're set up and interacted with.
Carl Norum
+3  A: 

Linux executes your program is running in user-mode (ring 3 on x86). Additionally, it's using page-based memory protection to limit the memory locations your program can access. In particular, your program attempts to write to 0xB8000 (the VGA framebuffer), which it does not have permission to modify. The processor's MMU detects this, and it throws a CPU exception. The Linux kernel handles this exception, and translates it to a segment violation signal. Assuming you haven't set up a custom handler for your signal, the kernel then kills your process. To avoid this and get full access to your hardware, you'll either need to write a Linux device driver which will run in kernel mode (ring 0 on x86) with full permissions, or bypass Linux entirely by writing your own operating system.

bcat
Yea thanks, the whole idea of writing to that address was the beginnings of making a text-based pokemon esque adventure game in the same vein as rogue, except with individual spaces for characters functioning like colored pixels on the screen. I can't thank you guys enough for taking the time to explain this to me.
N8-bit