_asm {} with gcc

Started by
11 comments, last by DAharon 22 years, 3 months ago
I am trying to use the following function with gcc in RH linux. It works in DOS, but won''t compile with gcc. void Mode13H(void) { _asm { mov AX, 0013H int 10H } } Can anyone tell me how to properly insert inline assembly into my linux programs when compiling with gcc? Thanks.
Advertisement
i didn''t think you were supposed to use an underscore (although I haven''t used inline assembly much, so I dunno for sure)
try:
  void Mode13H(void) {asm {mov AX, 0013Hint 10H}}  
GCC has a different asm-syntax than most other x86 compilers/assemblers. It uses the AT&T syntax as opposed to the Intel syntax. You should write something like:
__asm__ (     "movw $0x13,%%ax\n"   "int $0x10\n");   

My AT&T syntax is a bit rusty, but I think it should work. (You can use simply 'asm' instead of '__asm__' if you prefer.)

Edited by - Dactylos on January 9, 2002 3:27:56 PM
Well, aside from not using AT&T syntax, the most obvious thing to me is you cannot use DOS interrupts in linux. In order to go that low level, you either have to use libc functions or write your own kernel module.
DOS does not own interrupts except its own software loadable ones. I think INT 10H is pretty much hard-wired into your system BIOS.

The nightmare travels across the cosmos with his burning mane. The trail of ash that is produced.

?Have a nice day!?

libc is just another piece of user level software, so it can''t execute interrupts, either.
Yes, int 10h is a BIOS interrupt, although it''s probably routed through by many TSRs (including DOS itself, though I''m not sure). Still, there''s no accessing real mode interrupts from a proper protected mode OS like Linux.

Anyway, gcc inline assembly is horrible. The code above would have to look like this:

  asm(   "movw $0x13,%%ax\n" /* actual assembly */   "int $0x10\n"   : /* output registers */   : /* input registers */   : "ax" /* modified registers */);  


The actual assembly isn''t touched by gcc at all: It''s just inlined into gcc''s assembly output. This is one of the more ugly aspects of inlining in gcc, as you''ll only get useless assembler messages if your assembly is wrong (i.e. line numbers are wrong, etc...)

Because gcc doesn''t touch the actual assembly, you need to tell it about the registers used in the assembly - otherwise the optimizer will screw up the code.
I can never remember the exact syntax of those out/in register parts though: Normally, I just look into the linux/arch/i386 tree of the kernel source whenever I need to write inline assembly

Oh, and the AT&T syntax is another problem. Arguments are the other way round, mnemonics have an added size indicator (e.g. movl for 4byte ops, movw for short ops and movb for byte ops). Also, constants are prefixed by a $, and registers are prefixed by a %.

Oh, and gcc does some kind of formatting to the assembly string: If you put %0 somewhere, it''ll be replaced by the register which is first named in the out/in/mod sections. You could rewrite the code above as:

  asm(   "movw $0x13,%0\n" /* actual assembly */   "int $0x10\n"   : /* output registers */   : /* input registers */   : "ax" /* modified registers */);  


Obviously, you can use %1, %2 etc... for additional registers.

Have fun *grins*

cu,
Prefect

One line of sourcecode says more than a thousand words.
Widelands - laid back, free software strategy
OK, well I can officially say that my days of incoporating inline assembly directly into my linux C programs are over before they even started.

So the next question would be this:
What would be the easiest way to enter mode 13H from linux?

I wasn''t using the assembly for speed of course, I was just using it because its the only way I know how to enter mode 13H.
there probably is a "int86" function that allows you to call MS-DOS interrupts from your "c" program. check for a "dos.h" in the include files.

To the vast majority of mankind, nothing is more agreeable than to escape the need for mental exertion... To most people, nothing is more troublesome than the effort of thinking.
To the vast majority of mankind, nothing is more agreeable than to escape the need for mental exertion... To most people, nothing is more troublesome than the effort of thinking.
Okay, that last post must be a joke, or else he just hadn''t seen the instances of the name "Linux" sprinkled around in this thread.
If memory servies me correctly, int 10h is the video interrupt. If you get it to work without completely screwing up the system, you''ll need to chown the program to root.

Low-level stuff on any UNIX type system is generally a Bad Thing (tm).

I''m guessing you''re trying to set the video mode? If so, use SVGAlib for it. It offers pretty much everything you''ll need to do, without having to get your hands icky with the screwed up AT&T asm syntax.

After careful deliberation, I have come to the conclusion that Nazrix is not cool. I am sorry for any inconvienience my previous mistake may have caused. We now return you to the original programming

This topic is closed to new replies.

Advertisement