• C

How to write to memory.

I am using an I/O card and can write to it in basic at address 0300h.
I have tried writing this:

char *p;
p = 0x300;

but the compiler does not let an address be asigned an integer.

How can I poke a byte to a defined address in memory ?
I really need to access 300, 301, 302 etc,
so the array pointer approach would be quite useful.
I am new to C so this may be quite obvious.
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

What you can do is enlarge an specific variable into an specific address in memory with realloc. Something like:

  char *p;
  realloc(p, sizeof(char));

But this will work only if the position 0x300 in memory is not busy or protected. Be careful with that.

I hope this will help you

What kind of rubbish is this?  'realloc' is to change the size of a malloc'ed block!  Or is it some sort of surrealist joke that I'm missing?

To the questioner.  From the address, I suspect you actually want to do an IO read/write, which means you have to use special functions 'inp' and 'outp'.  Check them out in your development system docs (I assume you're using a 16-bit DOS compiler, otherwise it's going to get difficult).  It would go something like:

  outp(0x300+i, mydata);

If you really want to do a memory read/write, you're on the right track.  All you have to do is force the compiler to do what you want with a cast, like this:

p=(char *)0x300;

If this is you want, reject the above answer and ask me to enter a null answer to give me the points.
Carlos032497Author Commented:
phillips, thank you for your answer. I do not believe it will work
though. Sorry.....miss.
prc I like your answer, but would like to try it. I will be happy to give you the points then. Your asumptions are right. Please enter your null answer.
Powerful Yet Easy-to-Use Network Monitoring

Identify excessive bandwidth utilization or unexpected application traffic with SolarWinds Bandwidth Analyzer Pack.

Carlos032497Author Commented:
I have tried

 outp(0x300+i, mydata);

although this does compile, the result is wrong. I have checked the documentation and outp(port, data) is the right syntac.
This does not work. Please try again.
prc is right in two ways: using reallic is idiotic and calling
function outp() is the way to go if you want to write
bytes to an I/O channel. Show us your BASIC program
(just the relevant parts please) and I'm sure one of us can
translate it to the equivalent C stuff ...

kind regards,


ps. I won't steal the answer away from prc ;-)
You'll have to reject the answer that is locking the question to get any further with this.  I agree with 'jos', let's see the BASIC.

jos - My main concern here is to kill off completely stupid answers like the above, which are becoming depressingly frequent - if you can solve the guy's problem, you're welcome to the points.

My guess is that it's not the outp() stuff that's causing
the problems; if it works in BASIC it should work in C;
I guess it's the C stuff itself that goofs (Carlos admitted
he's new to C, so ...)

Let's just sit back and wait for the BASIC ;-)

kind regards,


ps. I still won't take those points; my parents raised me (long ago)
this way to be polite (and I'm still suffering from it ;-)

Carlos032497Author Commented:
Here is the basic programme, which tests the I/O card.

10 bASEADD% = &H300
20 OUT bASEADD% + 3, 128
25 FOR J = 1 TO 10
40 OUT bASEADD% + 1, &HFF
50 OUT bASEADD% + 2, &HFF
70 GOSUB 140
80 OUT bASEADD%, 0
90 OUT bASEADD% + 1, 0
100 OUT bASEADD% + 2, 0
120 GOSUB 140
130 NEXT J
135 END
140 FOR i = 1 TO 10000
150 NEXT i

line 20 sets the card to output. The program then
outputs FF to set all bits in 3 bytes to 1. Then
writes all zeros. Once I can access the card I can
extend the program to application.

I have marked the original answer as F.
How else can I reject the answer?
Here's a line by line translation of your BASIC program:

/* 10 bASEADD% = &H300  */
int main() {

void gosub140(void);
int bASEADD = 0x300;
int j;

/* 20 OUT bASEADD% + 3, 128 */
outp(bASEADD+3, 128);

/* 25 FOR J = 1 TO 10 */
for (j= 1; j <= 10; j++) {

/* 30 OUT bASEADD%, &HFF */
outp(bASEADD, 0xff);

/* 40 OUT bASEADD% + 1, &HFF */
outp(bASEADD, 0xff);

/* 50 OUT bASEADD% + 2, &HFF */
outp(bASEADD+2, 0xff);

/* 60 PRINT "LOGIC 1"  */
printf("LOGIC 1\n");

/* 70 GOSUB 140 */


/* 80 OUT bASEADD%, 0 */
outp(bASEADD, 0);

/* 90 OUT bASEADD% + 1, 0 */
outp(bASEADD+1, 0);

/* 100 OUT bASEADD% + 2, 0 */
outp(bASEADD+2, 0);

/* 110 PRINT "LOGIC 0"  */
printf("LOGIC 0\n");

/* 120 GOSUB 140 */

/* 130 NEXT J */

/* 135 END */
return 0;


/* 140 FOR i = 1 TO 10000 */
/* 150 NEXT i  */
/* 160 RETURN  */

void gosub140() {

int i;

for (i= 1; i < 10000; i++)


Note that this type of delay is extremely unreliable; it depends
on your machine, your clock, other processes, and sometimes
even the face of the moon ... ;-)

kind regards,


ps. Wait for prc to submit his (empty?) answer and grade him
  for this, 'cause he came up with the essential clues to the
  answer of your question.
That's very nice, thank you.  There should be a way of splitting the points between exports, I think.

Just so it doesn't seem I'm getting something for nothing, jos is right that that kind of delay in C is very dubious.  Of course, 10000 loops in C are a hell of a lot faster than BASIC, anyway, but as written, a good optimising compiler can (and will) remove that loop entirely, on the basis that it doesn't do anything, and no-one is interested in the value of 'i' at the end of it.

To ensure that it doesn't throw the loop away, you have to make 'i' volatile, which says "I know something magic about this which means you can't optimise it".

So, the last bit should be

void gosub140()
  volatile int i;

  for (i= 0; i < 10000; i++)


Note that I start from zero - as written it only does 9999 loops (sorry to nitpick, jos!).  You could also use <= to make it more like the BASIC, but counting from zero is the standard way in C.

If you want a delay longer than a tenth of a second, you can use 'clock()' to get an exact time which will work whatever the speed of your processor.

Try this:

void gosub140()
  clock_t start = clock();

  /* Delay for half a second */
  while (clock() < start + CLOCKS_PER_SEC/2)
While on the subject of volatile, I forgot to say that if you use a 'char *' to write to memory, this ought to be volatile as well, otherwise the compiler might say, "I'm writing two values to the same place here - I'll just do the last one".  Doesn't look like you need to do this, though.




Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Carlos032497Author Commented:
Well guys. I am impressed. I tried the program and it worked first time. The leds are flashing merrily. Now the real work begins.

I am sorry that jos does not get more credit for this as his coding was good, bar the small coding error on line 40.

Thanks for your help. Good job.

I shall be back!
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.