Mail Archives: djgpp/1999/03/17/01:37:11
In article <36EE7597 DOT C0DF33F4 AT home DOT com>, BRAD KRANE
<nuclearmayhem AT home DOT com> wrote:
> Why is it that when I declaire a function that it always gives me a
>parse error on the line right after the first { in the function? How do
>I fix this. I put an example of one of the functions that I made that
>gives me the error sorry about the caps.
>Thanks.
>
> ~NuclearMayhem~
>
>unsigned char outp(short int port, unsigned char value)
>{
> asm { /* GIVES ME THE PARSE ERROR RIGHT
>HERE */
> XOR AX, AX
> XOR DX, DX
> MOV DX, port
> MOV AL, value
> OUT DX, AL
> }
>}
um, does this happen when you write a straight C function?
It's giving you a parse error because you're not using correct in-line
assembly format, nor are you using asm() correctly.
It -should- be (though I'm not totally sure, since I don't use inline
asm much, and never access ports in asm):
asm("outb %al,%dx"::"a" (value),"d" (port));
a quick breakdown of the changes made:
note the inlined assembly is within parentheses, not curly brackets
(what in tarnation do you call { and }?), and the statements are in
quotes, and in lowercase.
the suffix 'b' on the opcode 'out' indicates that the output is byte
length. it isn't always necessary to specify instruction lengths in gcc
assembler syntax (also called AT&T syntax), but it -is- recommended.)
the order of the operands are reversed. AT&T syntax is
source,destination. Always.
The percent sign before the registers indicates that they are indeed
registers. Intel syntax (which you are used to) doesn't require any symbol
before a register name, but AT&T does.
I couldn't see any point to clearing the registers before putting
anything in them, so I left that out.
This bit..
:"a" (value),"d" (port)
tells gcc to place the variable value in register 'a', and port in
register "d". Why not do it yourself? GCC might find that those values
have already been loaded into those registers, and can save itself from
reloading the variables redundantly.
In otherwords, assembler syntax in DJGPP is completely different than
assembler syntax for any conventional assembler.
Also, it seems that you may be thinking in terms of coding in real mode
with memory segmentation and all that jive. DJGPP assembler uses protected
mode with a flat memory model. It'll take some getting used to, but it's
much easier to write in than real mode and your programs will run faster
on modern CPU's (theoretically).
I also like AT&T syntax 1000000 times more than Intel syntax, but that's
probably because it resembles motorola syntax more (680x0 series).
Anyway, for more complete info on using in-line assembly in djgpp, visit
brennan underwood's orphaned FAQ on the subject, at
http://www.rt.e-technik.tu-darmstadt.de/~georg/djgpp/
also, check out the info file on gnu assembler (gas, or as).
Assuming you've installed that part of the package, type
info as
at the command line and read through the docs avialable, especially under
the "Machine Dependancies: 1386 dependancies" section.
- Raw text -