Page 1 of 1

Help with GAS inline assembly in real mode

Posted: Thu Sep 26, 2013 3:00 pm
by madmax
Hey everyone,

I'm GNU to this board. I've been trying to work on writing a toy os, just to play around with and learn about the x86 architechture. That being said, I'm having issues with some inline assembly. Here is the portion of assembly:

Code: Select all

/*reads a character*/
#define getchar() ({                             \
      char data = 0;		                \
      asm volatile(                                 \
		   "sti\n\t"			        \
		   "mov $0x00, %%ah\n\t"	\
		   "int $0x16\n\t"		        \
		   "mov %%al,%0"		\
		   :"=r" (data)			\
				       );	        \
      data;})
So that crud get's called later in kernel_main() like this:
char whatever = getchar();

And it doesn't work. Please note that I've been able to write to the VGA, and I've gotten text to the string without any of the bios interrupts.

What's wrong with this? Why aren't my bios interrupts working? Please help!

Re: Help with GAS inline assembly in real mode

Posted: Thu Sep 26, 2013 3:03 pm
by kfreezen
Try putting it into a function.

Code: Select all

unsigned char getchar() {
 ...
 return data;
}
and see if that helps.

One reason your code isn't working is the fact that "data" isn't transferred into "whatever" when you "call" getchar()

Re: Help with GAS inline assembly in real mode

Posted: Thu Sep 26, 2013 3:12 pm
by madmax
I just tried that, and the same thing happens:
1. compile without errors (good:))
2. link fine

3. open with qemu-system... -kernel myos.bin

4. qemu opens, then the bios text disappears, then it seems like my prompt char ('>') is being put on the screen at the top left hand like it should be, but then the qemu menu comes back up.

Re: Help with GAS inline assembly in real mode

Posted: Thu Sep 26, 2013 3:17 pm
by kfreezen
Are you compiling it as 32-bit code? AFAIK the "-kernel" switch sets your kernel up as if it was multiboot compliant (which includes putting it into 32-bit protected mode), and if you don't take any steps to switch back to real mode, your code will triple fault without any sort of IDT. Also, BIOS interrupts are invalid in 32-bit (not sure about 16-bit) protected mode.

Re: Help with GAS inline assembly in real mode

Posted: Thu Sep 26, 2013 3:25 pm
by madmax
kernel.c:

Code: Select all

#include <stddef.h>
#include <stdint.h>

/*reads a character*/
unsigned char getchar() {                            
  char data = 0;		                
  asm volatile(                             
	       "sti\n\t"			
	       "mov $0x00, %%ah\n\t"	
	       "int $0x16\n\t"		
	       "mov %%al,%0"		
	       :"=r" (data)			
					    );	
  return data;
}
 
#if defined(__cplusplus)
extern "C" /* Use C linkage for kernel_main. */
#endif
void kernel_main() {
  unsigned char x = getchar();
  
  terminal_putchar(x);
}
boot.s:

Code: Select all

.section .multiboot
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM

.section .bootstrap_stack
stack_bottom:
.skip 16384 # 16 KiB
stack_top:

.section .text
.global _start
.type _start, @function
_start:
	call kernel_main
        jmp _hang
_hang:
        jmp _hang
That seems like a reasonable explanation, thank you.

Re: Help with GAS inline assembly in real mode

Posted: Thu Sep 26, 2013 3:33 pm
by kfreezen
Yes, that is your problem. If you want to get to the point where you can read characters from the keyboard in protected mode, look to either http://github.com/jmolloy/JMTK, http://jamesmolloy.co.uk/tutorial_html/index.html, or http://www.osdever.net/tutorials/view/b ... t-tutorial. The newest (and supposedly more recommended tutorial) is the first.

Re: Help with GAS inline assembly in real mode

Posted: Thu Sep 26, 2013 3:45 pm
by madmax
Thanks for those links, I'll be sure to check them out!