By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,132 Members | 1,948 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,132 IT Pros & Developers. It's quick & easy.

Register variables

P: n/a
Please clear my doubt. When do we declare a variable to be a register
variable? What is its significance? What are the conditions to be
adhered to when register variables are passed between functions?

Feb 22 '07 #1
Share this Question
Share on Google+
28 Replies


P: n/a
"so*********@gmail.com" <so*********@gmail.comwrote:
Please clear my doubt. When do we declare a variable to be a register
variable?
We don't. Modern compilers are, in 99.99% of all cases, better at
determining such matters than programmers are.

Richard
Feb 22 '07 #2

P: n/a
so*********@gmail.com wrote:
Please clear my doubt. When do we declare a variable to be a register
variable? What is its significance? What are the conditions to be
adhered to when register variables are passed between functions?
When to declare: As Richard Bos and Captain Corcoran say,
"Never. Well, hardly ever."

Significance: In the Old Days, `register' was a hint that
the compiler should try to hold the variable in a CPU register
instead of in memory. Compilers have become much better at
making these decisions unaided, and such hints can be counter-
productive; many compilers ignore the hint. The remaining
effect of `register' is to declare that "No pointer can point
at this variable."

Conditions for passing: None, because `register' variables
are never passed to and from functions. Neither are `auto'
variables or `static' variables or any kinds of variables at
all: C functions receive and return *values*, not variables.

--
Eric Sosman
es*****@acm-dot-org.invalid
Feb 22 '07 #3

P: n/a
so*********@gmail.com wrote:
Please clear my doubt. When do we declare a variable to be a register
variable? What is its significance? What are the conditions to be
adhered to when register variables are passed between functions?
The qulifier 'register' used to suggest to the compiler that the
object concerned is likely to be heavily accessed and hence should
preferably be stored in a machine register. Registers are a collection
of very fast memory cells, most often within the processor itself.
Note that the use of register is merely a suggestion to the compiler,
which is free to ignore it.

Current compilers are, in almost all cases, better at allocating
registers than a programmer would be. Hence the register specifier is
mostly a relic from the past that you should not have to worry about.

As for it's restrictions, only auto objects can be qualified with
register and the address of a register qualified object may not be
taken, i.e. the & operator cannot be used.

Feb 22 '07 #4

P: n/a
Eric Sosman wrote:
>so*********@gmail.com wrote:
>... When do we declare a variable to be a register
variable? ...
>...In the Old Days, `register' was a hint that
the compiler should try to hold the variable in a CPU register
instead of in memory. ...
[Trivia][Folklore][Old-wife-tales]

Which reminded me of the following. (Can anybody confirm this? I can
not find the original reference.)

In the Old Days, there was an original C compiler for PDP-11 Unix.

I read that this compiler had a very simple approach for handling
register declarations. Three of the CPU registers were reserved for
this purpose. The first three variables declared as 'register' were
assigned to them in the order of declaration. Any more were ignored.

The contents of these registers was preserved across function calls,
making possible to use register declarations as an alternate parameter
passing mechanism without the overhead of pushing/popping data to the
stack, and it was inevitably used in this fashion by people wanting to
squeeze more performance from the system.

So for example, the following code snipped "should" work:

f1()
{
register a1, b1, c1;
a1 = 10;
b1 = 20;
c1 = a1 + b1;
f2();
}

f2()
{
register a2, b2, c2 ;
/* prints "10 + 20 = 30" */
printf("%d + %d = %d\n", a2, b2, c2);
}
Roberto Waltman

[ Please reply to the group,
return address is invalid ]
Feb 22 '07 #5

P: n/a
On Feb 22, 8:12 am, "sowmiyak...@gmail.com" <sowmiyak...@gmail.com>
wrote:
Please clear my doubt. When do we declare a variable to be a register
variable? What is its significance? What are the conditions to be
adhered to when register variables are passed between functions?
The register keyword is only a suggestion, which compilers are free to
ignore.
However, it does place new restrictions on your code, because you
can't take the address of a register.

So:

void foo(void)
{
register int bar;
int *p = &bar; /* This is not allowed. Remove the register keyword on
bar and it's fine */
}

There may be some very rare instances where a compiler hint will
help. For the most part, it's silly to do it today.

Feb 22 '07 #6

P: n/a
On Thu, 22 Feb 2007 12:47:59 -0500, Roberto Waltman
<us****@rwaltman.netwrote:
>Eric Sosman wrote:
>>so*********@gmail.com wrote:
>>... When do we declare a variable to be a register
variable? ...
>>...In the Old Days, `register' was a hint that
the compiler should try to hold the variable in a CPU register
instead of in memory. ...

[Trivia][Folklore][Old-wife-tales]

Which reminded me of the following. (Can anybody confirm this? I can
not find the original reference.)

In the Old Days, there was an original C compiler for PDP-11 Unix.

I read that this compiler had a very simple approach for handling
register declarations. Three of the CPU registers were reserved for
this purpose. The first three variables declared as 'register' were
assigned to them in the order of declaration. Any more were ignored.
Here is a link to two of those compilers. You can check it out for
yourself: http://cm.bell-labs.com/cm/cs/who/dmr/primevalC.html

<snip>
--
ArarghMail702 at [drop the 'http://www.' from ->] http://www.arargh.com
BCET Basic Compiler Page: http://www.arargh.com/basic/index.html

To reply by email, remove the garbage from the reply address.
Feb 22 '07 #7

P: n/a
On Feb 22, 12:47 pm, Roberto Waltman <use...@rwaltman.netwrote:
Eric Sosman wrote:
sowmiyak...@gmail.com wrote:
... When do we declare a variable to be a register
variable? ...
...In the Old Days, `register' was a hint that
the compiler should try to hold the variable in a CPU register
instead of in memory. ...

[Trivia][Folklore][Old-wife-tales]

Which reminded me of the following. (Can anybody confirm this? I can
not find the original reference.)

In the Old Days, there was an original C compiler for PDP-11 Unix.

I read that this compiler had a very simple approach for handling
register declarations. Three of the CPU registers were reserved for
this purpose. The first three variables declared as 'register' were
assigned to them in the order of declaration. Any more were ignored.

The contents of these registers was preserved across function calls,
making possible to use register declarations as an alternate parameter
passing mechanism without the overhead of pushing/popping data to the
stack,
Seems an unlikely and not very useful arrangement, since the inner
function could not actually modify those variables - unless the user
wrote explicit code to save and restore them in the caller?

And of course this could only have been a "primeval C", since in this
manner it violates the semantics of what we today understand as C and
is not a compiler "feature" but a quirk of language design (or a bug).
and it was inevitably used in this fashion by people wanting to
squeeze more performance from the system.

So for example, the following code snipped "should" work:

f1()
{
register a1, b1, c1;
a1 = 10;
b1 = 20;
c1 = a1 + b1;
f2();
}

f2()
{
register a2, b2, c2 ;
/* prints "10 + 20 = 30" */
printf("%d + %d = %d\n", a2, b2, c2);
}

Roberto Waltman

[ Please reply to the group,
return address is invalid ]

Feb 22 '07 #8

P: n/a
Roberto Waltman wrote:
>
[Trivia][Folklore][Old-wife-tales]

Which reminded me of the following. (Can anybody confirm this? I can
not find the original reference.)

In the Old Days, there was an original C compiler for PDP-11 Unix.

I read that this compiler had a very simple approach for handling
register declarations. Three of the CPU registers were reserved for
this purpose. The first three variables declared as 'register' were
assigned to them in the order of declaration. Any more were ignored.

The contents of these registers was preserved across function calls,
making possible to use register declarations as an alternate parameter
passing mechanism without the overhead of pushing/popping data to the
stack, and it was inevitably used in this fashion by people wanting to
squeeze more performance from the system.
I haven't seen registers was preserved across function calls in thus
way, but I have seen registers used as 'in' and 'out' registers to avoid
pushing parameters before a function call.

The same concept is used by some RISC machines (Sparc being one example)
where register 'wheels' with in, working and out registers on each
'spoke' are used to optimise function calls.

--
Ian Collins.
Feb 22 '07 #9

P: n/a
Roberto Waltman wrote:
Eric Sosman wrote:
so*********@gmail.com wrote:
... When do we declare a variable to be a register
variable? ...
...In the Old Days, `register' was a hint that
the compiler should try to hold the variable in a CPU register
instead of in memory. ...

[Trivia][Folklore][Old-wife-tales]

Which reminded me of the following. (Can anybody confirm this? I can
not find the original reference.)

In the Old Days, there was an original C compiler for PDP-11 Unix.

I read that this compiler had a very simple approach for handling
register declarations. Three of the CPU registers were reserved for
this purpose. The first three variables declared as 'register' were
assigned to them in the order of declaration. Any more were ignored.

The contents of these registers was preserved across function calls,
making possible to use register declarations as an alternate parameter
passing mechanism without the overhead of pushing/popping data to the
stack, and it was inevitably used in this fashion by people wanting to
squeeze more performance from the system.

So for example, the following code snipped "should" work:

f1()
{
register a1, b1, c1;
a1 = 10;
b1 = 20;
c1 = a1 + b1;
f2();
}

f2()
{
register a2, b2, c2 ;
/* prints "10 + 20 = 30" */
printf("%d + %d = %d\n", a2, b2, c2);
}
On an emulated PDP11 running V7 UNIX, I get this:

1,$p
#include <stdio.h>

f1()
{
register a1, b1, c1;
a1 = 10;
b1 = 20;
c1 = a1 + b1;
f2();
}

f2()
{
register a2, b2, c2 ;
/* prints "10 + 20 = 30" */
printf("%d + %d = %d\n", a2, b2, c2);
}

main() { f2(); }
w
234
q
# cc test.c -o test
# ./test
0 + 0 = 0
#

(Its <stdio.hdoes not declare printf; it only declares the functions
fopen, freopen, fdopen, ftell and fgets because of their return types.
But including it anyway doesn't cause any harm.)

Feb 22 '07 #10

P: n/a
Ar*****************@NOT.AT.Arargh.com wrote:
>Here is a link to two of those compilers. You can check it out for
yourself: http://cm.bell-labs.com/cm/cs/who/dmr/primevalC.html
Thanks, I did some time ago. The two versions in Mr. Ritchie's page
predate the introduction of the "register" keyword. (Keyword list is
initialized in c00.c) I guess the expression I used, "original C
compiler", is to vague.
"toby" <to**@telegraphics.com.auwrote:
>Seems an unlikely and not very useful arrangement,
Not that I am recommending to do this, but this would have been a
"very useful arrangement" in systems with very limited resources.
Not different in principle from people finding out what unused opcodes
do in a processor and, against all logic, using them in their code.
There were times when 24K words was considered a lot of memory, and
instruction execution times were measured in microseconds, not
nanoseconds.
>... since the inner
function could not actually modify those variables - unless the user
wrote explicit code to save and restore them in the caller?
If these registers were indeed preserved across function calls, values
could have been transferred in both directions. I wrote "could have"
instead of the more definite "would have" because flow analysis could
allow reusing the register for a different purpose, although I doubt
these compilers did that.
>And of course this could only have been a "primeval C", since in this
manner it violates the semantics of what we today understand as C and
is not a compiler "feature" but a quirk of language design (or a bug).
Of course, guilty on all counts ...

Roberto Waltman

[ Please reply to the group,
return address is invalid ]
Feb 22 '07 #11

P: n/a
"Harald van D?k" <tr*****@gmail.comwrote:
>
On an emulated PDP11 running V7 UNIX, I get this:
...
Thanks for checking.
>
main() { f2(); }
^
Better f1()

Is the default compiler in V7 a derivative of the original(s), or the
"Portable C Compiler"?
>w
234
q
# cc test.c -o test
# ./test
0 + 0 = 0
#
Roberto Waltman

[ Please reply to the group,
return address is invalid ]
Feb 22 '07 #12

P: n/a
In article <i3********************************@4ax.com>,
Roberto Waltman <us****@rwaltman.netwrote:
If these registers were indeed preserved across function calls, values
could have been transferred in both directions. I wrote "could have"
instead of the more definite "would have" because flow analysis could
allow reusing the register for a different purpose, although I doubt
these compilers did that.
Maybe I am not thinking about this correctly, but I don't see how these
register variables could possibly be used to return values? When the
function returns, the register preservation mechanism would overwrite
the registers with their original values would it not?
Regards,

John Byrns

--
Surf my web pages at, http://fmamradios.com/
Feb 22 '07 #13

P: n/a
Roberto Waltman wrote:
"Harald van D?k" <tr*****@gmail.comwrote:

On an emulated PDP11 running V7 UNIX, I get this:
...

Thanks for checking.

main() { f2(); }
^
Better f1()
Oh dear. Sorry, you're completely right, of course, and that does
result in the output you expected ("10 + 20 = 30").
Is the default compiler in V7 a derivative of the original(s), or the
"Portable C Compiler"?
There is a pcc script, and the runtime behaviour is the same when
compiling using that, so it's probably that, but I'll need to check
more carefully to be sure.

Feb 22 '07 #14

P: n/a
Harald van Dijk wrote:
Roberto Waltman wrote:
Is the default compiler in V7 a derivative of the original(s), or the
"Portable C Compiler"?

There is a pcc script, and the runtime behaviour is the same when
compiling using that, so it's probably that, but I'll need to check
more carefully to be sure.
No, the default compiler and pcc are different, although they have a
common preprocessor, optimiser and linker.

Feb 22 '07 #15

P: n/a
John Byrns <by****@sbcglobal.netwrote:
>..
Maybe I am not thinking about this correctly, but I don't see how these
register variables could possibly be used to return values? When the
function returns, the register preservation mechanism would overwrite
the registers with their original values would it not?
Not necessarily. The code generated by the compiler should preserve
only as much of the processor state as deemed necessary to continue
after a function call returns.
In a traditional register oriented architecture like the PDP-11, (to
limit the discussion to scenarios in which actually there *are*
registers,) this may include all registers, some, or none (other than
program counter and stack pointer.)
I would expect most compiler calling conventions to fall in the 'some'
group.

Roberto Waltman

[ Please reply to the group,
return address is invalid ]
Feb 22 '07 #16

P: n/a
"Harald van D?k" wrote:
>... and that does
result in the output you expected ("10 + 20 = 30").
Bingo! Thanks. I pity the soul trying to debug code using this
"feature" through several levels of function calls...

Roberto Waltman

[ Please reply to the group,
return address is invalid ]
Feb 22 '07 #17

P: n/a
"toby" <to**@telegraphics.com.auwrites:
On Feb 22, 12:47 pm, Roberto Waltman <use...@rwaltman.netwrote:
>Eric Sosman wrote:
>sowmiyak...@gmail.com wrote:
... When do we declare a variable to be a register
variable? ...
...In the Old Days, `register' was a hint that
the compiler should try to hold the variable in a CPU register
instead of in memory. ...

[Trivia][Folklore][Old-wife-tales]

Which reminded me of the following. (Can anybody confirm this? I can
not find the original reference.)

In the Old Days, there was an original C compiler for PDP-11 Unix.

I read that this compiler had a very simple approach for handling
register declarations. Three of the CPU registers were reserved for
this purpose. The first three variables declared as 'register' were
assigned to them in the order of declaration. Any more were ignored.

The contents of these registers was preserved across function calls,
making possible to use register declarations as an alternate parameter
passing mechanism without the overhead of pushing/popping data to the
stack,

Seems an unlikely and not very useful arrangement, since the inner
function could not actually modify those variables - unless the user
wrote explicit code to save and restore them in the caller?

And of course this could only have been a "primeval C", since in this
manner it violates the semantics of what we today understand as C and
is not a compiler "feature" but a quirk of language design (or a bug).
It seems perfectly plausible that it would work that way, possibly
even in a modern compiler.
>and it was inevitably used in this fashion by people wanting to
squeeze more performance from the system.

So for example, the following code snipped "should" work:

f1()
{
register a1, b1, c1;
a1 = 10;
b1 = 20;
c1 = a1 + b1;
f2();
}

f2()
{
register a2, b2, c2 ;
/* prints "10 + 20 = 30" */
printf("%d + %d = %d\n", a2, b2, c2);
}
The variables a2, b2, and c2 in the f2() function are not initialized.
Since they're automatic variables, their initial values are garbage.
If the compiler assigns them to the same registers it used for a1, b2,
and c1 in f1(), then the garbage value are going to be whatever was
already in those variables.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 22 '07 #18

P: n/a
Roberto Waltman <us****@rwaltman.netwrites:
>
Which reminded me of the following. (Can anybody confirm this? I can
not find the original reference.)

In the Old Days, there was an original C compiler for PDP-11 Unix.

I read that this compiler had a very simple approach for handling
register declarations. Three of the CPU registers were reserved for
this purpose. The first three variables declared as 'register' were
assigned to them in the order of declaration. Any more were ignored.
This much is true. As C spread to other platforms, this meant that
the first N register declarations were obeyed (for some
machine-specific N),and the rest ignored.

There was a hilarious sequence of benchmarking dirty tricks that
turned up on usenet sometime in the early 1980s:

Intel fan: my machine is faster than Motorola, on the basis of my
benchmark.

Motorola fan: no fair! you didn't use register variables. Now that
I've put all the variables in registers, my machine is faster.

Intel fan: no fair! the order of the variables didn't put the
most-used ones first! I reorded the variable declarations and now my
machine is faster!

I don't remember if there was another round.
The contents of these registers was preserved across function calls,
making possible to use register declarations as an alternate parameter
passing mechanism without the overhead of pushing/popping data to the
stack, and it was inevitably used in this fashion by people wanting to
squeeze more performance from the system.
Not that I've heard of. Given the level of smarts in the linker, I'd
be really surprised.
Feb 22 '07 #19

P: n/a
"Harald van Dijk" <tr*****@gmail.comwrites:
Roberto Waltman wrote:
>"Harald van D?k" <tr*****@gmail.comwrote:
>
On an emulated PDP11 running V7 UNIX, I get this:
...

Thanks for checking.
>
main() { f2(); }
^
Better f1()

Oh dear. Sorry, you're completely right, of course, and that does
result in the output you expected ("10 + 20 = 30").
[...]

I just tried something similar:
================================
#include <stdio.h>

void set_registers(void)
{
register int x0, x1, x2, x3, x4, x5, x6, x7, x8, x9;
x0 = 100;
x1 = 101;
x2 = 102;
x3 = 103;
x4 = 104;
x5 = 105;
x6 = 106;
x7 = 107;
x8 = 108;
x8 = 109;
}

void read_registers(void)
{
register int y0, y1, y2, y3, y4, y5, y6, y7, y8, y9;
printf("%d %d %d %d %d %d %d %d %d %d\n",
y0, y1, y2, y3, y4, y5, y6, y7, y8, y9);
}

int main(void)
{
set_registers();
read_registers();
return 0;
}
================================

On most compilers and platforms, I got garbage output. But using
Sun's C compiler on Solaris/SPARC, I got the following output:

100 101 102 103 104 105 106 107 -12788660 200

Apparently the compiler re-used the same 8 registers for the first 8
"register" variables in each function, and didn't clobber them between
the calls.

You could do the same thing using something like "static register"
variables if there were such a thing.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 23 '07 #20

P: n/a
Keith Thompson <ks***@mib.orgwrote:
>I just tried something similar:
================================
#include <stdio.h>

void set_registers(void)
{
register int x0, x1, x2, x3, x4, x5, x6, x7, x8, x9;
x0 = 100;
x1 = 101;
x2 = 102;
x3 = 103;
x4 = 104;
x5 = 105;
x6 = 106;
x7 = 107;
x8 = 108;
x8 = 109;
^
x9 not initialized.
Your findings are still valid.
>}

void read_registers(void)
{
register int y0, y1, y2, y3, y4, y5, y6, y7, y8, y9;
printf("%d %d %d %d %d %d %d %d %d %d\n",
y0, y1, y2, y3, y4, y5, y6, y7, y8, y9);
}

int main(void)
{
set_registers();
read_registers();
return 0;
}
================================

On most compilers and platforms, I got garbage output. But using
Sun's C compiler on Solaris/SPARC, I got the following output:

100 101 102 103 104 105 106 107 -12788660 200

Apparently the compiler re-used the same 8 registers for the first 8
"register" variables in each function, and didn't clobber them between
the calls.

You could do the same thing using something like "static register"
variables if there were such a thing.
Yes. I thought of the similarity to global/static variables in a
previous post. Did not mention it because I was not sure if the
analogy breaks somewhere.

Roberto Waltman

[ Please reply to the group,
return address is invalid ]
Feb 23 '07 #21

P: n/a
Keith Thompson wrote:
>
I just tried something similar:
================================
#include <stdio.h>

void set_registers(void)
{
register int x0, x1, x2, x3, x4, x5, x6, x7, x8, x9;
x0 = 100;
x1 = 101;
x2 = 102;
x3 = 103;
x4 = 104;
x5 = 105;
x6 = 106;
x7 = 107;
x8 = 108;
x8 = 109;
}

void read_registers(void)
{
register int y0, y1, y2, y3, y4, y5, y6, y7, y8, y9;
printf("%d %d %d %d %d %d %d %d %d %d\n",
y0, y1, y2, y3, y4, y5, y6, y7, y8, y9);
}

int main(void)
{
set_registers();
read_registers();
return 0;
}
================================

On most compilers and platforms, I got garbage output. But using
Sun's C compiler on Solaris/SPARC, I got the following output:

100 101 102 103 104 105 106 107 -12788660 200

Apparently the compiler re-used the same 8 registers for the first 8
"register" variables in each function, and didn't clobber them between
the calls.

You could do the same thing using something like "static register"
variables if there were such a thing.
That'll be the working registers on the second spoke of the register wheel.

With SPARC, the each function call level (up to in implementation
defined limit) has in, working and out registers. The out registers
from one level become the in for the next, enabling some parameters to
be passed without using the stack.

--
Ian Collins.
Feb 23 '07 #22

P: n/a
On Thu, 22 Feb 2007 16:04:45 -0500, Roberto Waltman
<us****@rwaltman.netwrote:
>Ar*****************@NOT.AT.Arargh.com wrote:
>>Here is a link to two of those compilers. You can check it out for
yourself: http://cm.bell-labs.com/cm/cs/who/dmr/primevalC.html

Thanks, I did some time ago. The two versions in Mr. Ritchie's page
predate the introduction of the "register" keyword. (Keyword list is
initialized in c00.c) I guess the expression I used, "original C
compiler", is to vague.
OK, here are some later versions. The v5 version of c00.c has the
register keyword. (I already had it on my system) I didn't check any
of the others.
http://mirror.cc.vt.edu/pub/projects...ions/research/

<snip>

I started here: http://minnie.tuhs.org/PUPS/ to get to the above. They
have lots of old stuff.
--
ArarghMail702 at [drop the 'http://www.' from ->] http://www.arargh.com
BCET Basic Compiler Page: http://www.arargh.com/basic/index.html

To reply by email, remove the garbage from the reply address.
Feb 23 '07 #23

P: n/a
"Roberto Waltman" <us****@rwaltman.netwrote in message
news:um********************************@4ax.com...
Which reminded me of the following. (Can anybody confirm this?
I can not find the original reference.)
I've seen something like this, but perhaps not exactly what you're
remembering.
I read that this compiler had a very simple approach for handling
register declarations. Three of the CPU registers were reserved for
this purpose. The first three variables declared as 'register' were
assigned to them in the order of declaration. Any more were ignored.
Yes.
The contents of these registers was preserved across function calls,
making possible to use register declarations as an alternate parameter
passing mechanism without the overhead of pushing/popping data to the
stack, and it was inevitably used in this fashion by people wanting to
squeeze more performance from the system.
In the case I'm remembering, the registers were pushed onto the stack, but
their former values remained. If the registers variables in the called
function were declared without initialization, they retained, positionally,
their previous values. So, you could get away with what you showed in yoru
code snippet. However, the results of any processing on them was lost on
exit from the function when the previous values were popped from the stack
on exit.

Thus:
f1() {
register a1, b, c;
a = 10; b = 20; c = a + b
f2()
printf("%d %d %d\n", a, b, c);
}

f2() {
register d, e, f;
printf("%d %d %d\n", d, e, f);
d++; e++; f = d + e;
printf("%d %d %d\n", d, e, f);
}

Produced:
10 20 30
11 21 33
10 20 30

Is that similar to what you're remembering?

Even more, the compiler had an automatic register optimization feature.
When this was turned on, the most often used local variables in the function
were put in registers. So, in the above, you could turn on this switch and
omit the "register" key word and get the same results. This was on a
MC68000 compiler I used in the 80's

- Bill

Feb 23 '07 #24

P: n/a

"John Byrns" <by****@sbcglobal.netwrote in message
news:by**************************@newsclstr02.news .prodigy.com...
.....
>
Maybe I am not thinking about this correctly, but I don't see how these
register variables [in V7 C] could possibly be used to return values?
When the
function returns, the register preservation mechanism would overwrite
the registers with their original values would it not?
You're thinking correctly. The call mechanism saved all 3 possible
register variables (no matter how many were in use), and
always restored them. Thus, by chance, you could pass
values in registers as was illustrated, but not get new values back.

Dennis
Feb 23 '07 #25

P: n/a
On Feb 23, 6:28 am, "Bill Leary" <Bill_Le...@msn.comwrote:
Even more, the compiler had an automatic register optimization feature.
When this was turned on, the most often used local variables in the function
were put in registers. So, in the above, you could turn on this switch and
omit the "register" key word and get the same results. This was on a
MC68000 compiler I used in the 80's
Yes, I believe most modern compilers discard the "register" directive
entirely, because it thinks it knows best. I was surprised the Sun one
didn't.

I guess that to reproduce-ish this, you could find out if there are
any registers the compiler doesn't touch or such, and do inline ASM
storing and retrieval of these... Ugh. :)

-Tore

Feb 23 '07 #26

P: n/a
"Tore Sinding Bekkedal" <to*****@gmail.comwrote in message
news:11*********************@k78g2000cwa.googlegro ups.com...
On Feb 23, 6:28 am, "Bill Leary" <Bill_Le...@msn.comwrote:
>Even more, the compiler had an automatic register optimization feature.
When this was turned on, the most often used local variables in the
function
were put in registers. So, in the above, you could turn on this switch
and
omit the "register" key word and get the same results. This was on a
MC68000 compiler I used in the 80's

Yes, I believe most modern compilers discard the "register" directive
entirely, because it thinks it knows best. I was surprised the Sun one
didn't.
I've read the internals notes on a number of compilers and have seen that
some say they permit, but don't utilize, "register." What most of them seem
to say is that they "optimize" or "attempt to optimize" access to variables
declared with "register." They don't actually say they'll use a register
for such a variable.

For embedded system compilers, the Metrowerks we use for Coldfire, for
example, there are explicit notes on how many register variables are
recognized. If I'm recalling correctly, the first seven integers and the
first three pointers declared with "register" are actually put in CPU
registers.
I guess that to reproduce-ish this, you could find out if there are
any registers the compiler doesn't touch or such, and do inline ASM
storing and retrieval of these... Ugh. :)
Thanks, no.

- Bill

Feb 23 '07 #27

P: n/a
On Feb 22, 4:04 pm, Roberto Waltman <use...@rwaltman.netwrote:
ArarghMail702NOS...@NOT.AT.Arargh.com wrote:
Here is a link to two of those compilers. You can check it out for
yourself:http://cm.bell-labs.com/cm/cs/who/dmr/primevalC.html

Thanks, I did some time ago. The two versions in Mr. Ritchie's page
predate the introduction of the "register" keyword. (Keyword list is
initialized in c00.c) I guess the expression I used, "original C
compiler", is to vague.

"toby" <t...@telegraphics.com.auwrote:
Seems an unlikely and not very useful arrangement,

Not that I am recommending to do this, but this would have been a
"very useful arrangement" in systems with very limited resources.
Not different in principle from people finding out what unused opcodes
do in a processor and, against all logic, using them in their code.
There were times when 24K words was considered a lot of memory, and
instruction execution times were measured in microseconds, not
nanoseconds.
... since the inner
function could not actually modify those variables - unless the user
wrote explicit code to save and restore them in the caller?

If these registers were indeed preserved across function calls, values
could have been transferred in both directions. I wrote "could have"
instead of the more definite "would have" because flow analysis could
allow reusing the register for a different purpose, although I doubt
these compilers did that.
And of course this could only have been a "primeval C", since in this
manner it violates the semantics of what we today understand as C and
is not a compiler "feature" but a quirk of language design (or a bug).

Of course, guilty on all counts ...
Almost. If I read you right, one mechanism falls into the "dirty
tricks" category, but is still (atrociously non portable) C:
exploiting that the callee's register variables overlap the caller's,
effectively passing some parameters in registers as initial values.

Even on the PDP-11 this doesn't seem much of a coup - you might avoid
a stack push and pop, but it also somewhat constrains the callee's use
of the variables in question. (In C, these registers would also still
have to be preserved across the call, precluding returns.)

But "scratch" register *variables* potentially clobbered by function
calls would not be "C", nor re-entrant.

Have I got this right?
>
Roberto Waltman

[ Please reply to the group,
return address is invalid ]

Feb 23 '07 #28

P: n/a
On Feb 22, 5:26 pm, Joe Pfeiffer <pfeif...@cs.nmsu.eduwrote:
Roberto Waltman <use...@rwaltman.netwrites:
Which reminded me of the following. (Can anybody confirm this? I can
not find the original reference.)
In the Old Days, there was an original C compiler for PDP-11 Unix.
I read that this compiler had a very simple approach for handling
register declarations. Three of the CPU registers were reserved for
this purpose. The first three variables declared as 'register' were
assigned to them in the order of declaration. Any more were ignored.

This much is true. As C spread to other platforms, this meant that
the first N register declarations were obeyed (for some
machine-specific N),and the rest ignored.

There was a hilarious sequence of benchmarking dirty tricks that
turned up on usenet sometime in the early 1980s:

Intel fan: my machine is faster than Motorola, on the basis of my
benchmark.

Motorola fan: no fair! you didn't use register variables. Now that
I've put all the variables in registers, my machine is faster.

Intel fan: no fair! the order of the variables didn't put the
most-used ones first! I reorded the variable declarations and now my
machine is faster!

I don't remember if there was another round.
The Dhrystone benchmark famously attracted a lot of dirty tricks and
compiler special-casing, since it was almost uselessly simpleminded.
I'm sure other a.f.c regulars can supply spicy details.
...
Feb 23 '07 #29

This discussion thread is closed

Replies have been disabled for this discussion.