In and Out on port space within C - any standard?

J

James Harris

I'm wanting to write in C some code in which it is necessary to address a device as I/O
space rather than as part of memory. I would like the code to be as standard - and hence
as portable - as possible. It's intended to be later ported to other hardware.

Options?

1) Set up some inline assembler in a header file. I believe I'd need to use the asm
keyword but that this isn't ansi C. Is that correct?
2) Write a separate routine in assembler (to do the actual in and out) and link it with
the C code.
3) Use the appropriate C calls - perhaps they already exist....?

I've seen asm overridden with __asm__ but how does that work? It may stop the compiler
complaining but doesn't it result in the same thing in the end?

Help much appreciated. I have checked the FAQ but searches on "asm" and "assem" returned
nothing.
 
M

Mike Wahler

James Harris said:
I'm wanting to write in C some code in which it is necessary to address a device as I/O
space rather than as part of memory.

Standard C doesn't support any direct device access at all, 'i/o space',
'memory', or otherwise.
I would like the code to be as standard - and hence
as portable - as possible. It's intended to be later ported to other hardware.

Options?

No portable ones.
1) Set up some inline assembler in a header file. I believe I'd need to use the asm
keyword but that this isn't ansi C. Is that correct?

The keyword is, but not the assembler statements themselves.
2) Write a separate routine in assembler (to do the actual in and out) and link it with
the C code.
3) Use the appropriate C calls - perhaps they already exist....?

Not standard ones. Standard C does not define any interfaces
with other languages.
I've seen asm overridden with __asm__ but how does that work?

However your implementor designed it. Consult your documentation.
It may stop the compiler
complaining but doesn't it result in the same thing in the end?

Help much appreciated. I have checked the FAQ but searches on "asm" and "assem" returned
nothing.

We can't help you here, because your project is outside the domain of
the standard language. Try checking support resources for your
particular implementation.

-Mike
 
J

James Harris

James Harris said:
I'm wanting to write in C some code in which it is necessary to address a device as I/O
space rather than as part of memory. I would like the code to be as standard - and hence
as portable - as possible. It's intended to be later ported to other hardware.

Options?

1) Set up some inline assembler in a header file. I believe I'd need to use the asm
keyword but that this isn't ansi C. Is that correct?
2) Write a separate routine in assembler (to do the actual in and out) and link it with
the C code.
3) Use the appropriate C calls - perhaps they already exist....?

I've seen asm overridden with __asm__ but how does that work? It may stop the compiler
complaining but doesn't it result in the same thing in the end?

Help much appreciated. I have checked the FAQ but searches on "asm" and "assem" returned
nothing.

I meant to add that I'd wondered if I should use a Pragma for this but all the FAQ says
about them is they are well defined escape-hatch. What does /that/ mean? - confused....
 
L

Leor Zolman

I'm wanting to write in C some code in which it is necessary to address a device as I/O
space rather than as part of memory. I would like the code to be as standard - and hence
as portable - as possible. It's intended to be later ported to other hardware.

Options?

1) Set up some inline assembler in a header file. I believe I'd need to use the asm
keyword but that this isn't ansi C. Is that correct?

Correct, nor even ISO C. Raspberries for the asm-in-header-file approach.
2) Write a separate routine in assembler (to do the actual in and out) and link it with
the C code.

That one gets my vote. Localize /all/ the platform-specific code into its
own dedicated module, and then use, say, conditional compilation to select
the platform to compile for.
3) Use the appropriate C calls - perhaps they already exist....?

No such Standard calls exist, no.
I've seen asm overridden with __asm__ but how does that work? It may stop the compiler
complaining but doesn't it result in the same thing in the end?

I don't know, but all that asm stuff should be in the platform-specific
module, however it works.
Help much appreciated. I have checked the FAQ but searches on "asm" and "assem" returned
nothing.

Good luck,
-leor



Leor Zolman
BD Software
(e-mail address removed)
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
 
M

Malcolm

James Harris said:
I'm wanting to write in C some code in which it is necessary to
address a device as I/O space rather than as part of memory.
There's no way of doing this portably. What you want to do is separate out
all the hardware interface code into a separate file, and then make the
functions C-callable.
How you actually write the hardware layer depends on your platform. Probably
you will have some version of the asm keyword that allows inline assembly
(and does a lot of book-keeping for you). However you will have to rewrite
the code to port to another platform, so keep it separated out and as short
as possible.
 
J

Jack Klein

James Harris said:
I'm wanting to write in C some code in which it is necessary to address a device as I/O
space rather than as part of memory.

Standard C doesn't support any direct device access at all, 'i/o space',
'memory', or otherwise.
[snip]
1) Set up some inline assembler in a header file. I believe I'd need to use the asm
keyword but that this isn't ansi C. Is that correct?

The keyword is, but not the assembler statements themselves.

I'm afraid you are thinking C++ here, not C. There is no "asm"
keyword in C, it has never been part of any standard, not even the
original 1989 ANSI one.
 
M

Mike Wahler

Jack Klein said:
On Sun, 29 Feb 2004 23:45:52 GMT, "Mike Wahler"


I'm afraid you are thinking C++ here, not C. There is no "asm"
keyword in C, it has never been part of any standard, not even the
original 1989 ANSI one.

Yes, oops. Thanks for the correction.

-Mike
 
P

Pierre Maurette

James Harris said:
I'm wanting to write in C some code in which it is necessary to address a device as I/O
space rather than as part of memory. I would like the code to be as standard - and hence
as portable - as possible. It's intended to be later ported to other hardware.

Options?

1) Set up some inline assembler in a header file. I believe I'd need to use the asm
keyword but that this isn't ansi C. Is that correct?

In C99 standard:

J.5.10 The asm keyword
1 The asm keyword may be used to insert assembly language directly into the
translator output (6.8). The most common implementation is via a statement
of the form:
asm ( character-string-literal );

Maybe you can try anything like writing conditional blocks in a header, one
per hardware.

typedef unsigned char u8;

For Intel with short port address (0 to 255), 8 bits wide ports:

const u8 PORT_IN = 0xF0;
const u8 PORT_OUT = 0xF4;

inline void getPort(u8 MemVar)
{
asm
{
push ax
in ax, PORT_IN
mov byte[MemVar], ax
pop ax
}
}

inline void setPort(u8 MemVar)
{
asm
{
push ax
mov ax, byte[MemVar]
out PORT_OUT, ax
pop ax
}
}

For another hardware with memory-mapped I/O:

const volatile u8* const PORT_IN = (volatile u8*) 0x00000412;
u8* const PORT_OUT = (volatile u8*) 0x0000041A;

inline void getPort(u8 MemVar){MemVar = PORT_IN;}

inline void setPort(u8 MemVar){PORT-_OUT = MemeVar;}

2) Write a separate routine in assembler (to do the actual in and out) and link it with
the C code.
Slow, no ? And no more portable.

Pierre
 
R

Richard Bos

In C99 standard:

J.5.10 The asm keyword

Note, first, that the name of that section is "Common Extensions", and
second, that most appendices, J included, aren't normative. IOW, this is
a description of what compiler writers have added to their compilers
besides C proper, it is not ISO C.
This means, for example, that when invoked in ISO mode, _no_ compiler is
allowed to complain about asm being used as a variable name, no matter
whether it provides an assembly extension or not.
1 The asm keyword may be used to insert assembly language directly into the
translator output (6.8). The most common implementation is via a statement
of the form:

Note: most common. _Not_ required, or even allowed in pure ISO mode.

Richard
 
C

CBFalconer

Pierre said:
In C99 standard:

J.5.10 The asm keyword
1 The asm keyword may be used to insert assembly language directly
into the translator output (6.8). The most common implementation
is via a statement of the form:

asm ( character-string-literal );

You omitted the precursor to that section, which is:

J.5 Common extensions

[#1] The following extensions are widely used in many
systems, but are not portable to all implementations. The
inclusion of any extension that may cause a strictly
conforming program to become invalid renders an
implementation nonconforming. Examples of such extensions
are new keywords, extra library functions declared in
standard headers, or predefined macros with names that do
not begin with an underscore.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top