lccwin fails to generate NOPs

  • Thread starter Edward Rutherford
  • Start date
E

Edward Rutherford

Hello

I am trying to write code that includes a certain number of NOPs in the
generated machine code, I would like to do it portably so without using
inline asm.

On lccwin, even without optimisations, no NOPs are generated. I have
searched the documentation but there does not seem to be any compiler
option covering NOP generation. Can anyone help?

Here is the C code:

main()
{
;
;
;
;
;
puts("done");
}

Here is the generated assembly - as you can see, the 5 NOPs are missing.

.file "c:\\nop_test.c"
_$M0:
.file "c:\\nop_test.c"
.text
.text
; 1 main()
.type _main,function
_main:
; 2 {
.line 2
; 3 ;
; 4 ;
; 5 ;
; 6 ;
; 7 puts("done");
.line 7
pushl $_$2
call _puts
addl $4,%esp
movl $0,%eax
_$1:
; 8 }
.line 8
ret
_$3:
.size _main,_$3-_main
.globl _main
.extern _puts
.data
_$2:
; "done\x0"
.byte 100,111,110,101,0
 
B

Ben Pfaff

Edward Rutherford said:
I am trying to write code that includes a certain number of NOPs in the
generated machine code, I would like to do it portably so without using
inline asm.

There is no portable way to do that.
 
G

glen herrmannsfeldt

In comp.compilers.lcc Edward Rutherford said:
I am trying to write code that includes a certain number of NOPs in the
generated machine code, I would like to do it portably so without using
inline asm.
On lccwin, even without optimisations, no NOPs are generated. I have
searched the documentation but there does not seem to be any compiler
option covering NOP generation. Can anyone help?

The "null statement" exists in many languages as a place to put a
statement label without attaching it to a statement that does
something else. Otherwise, it is also convenient sometimes for
the grammar to allow for it for other reasons. In C, for example,
it is sometimes needed as the statement in a for or while loops.

while(something()) ;

I have never known a compiler, for any language, to generate
assembly NOP for the null statement.
Here is the C code:
main()
{
;
;
;
;
;
puts("done");
}

-- glen
 
J

jacob navia

Le 04/01/11 23:30, Edward Rutherford a écrit :
Hello

I am trying to write code that includes a certain number of NOPs in the
generated machine code, I would like to do it portably so without using
inline asm.

On lccwin, even without optimisations, no NOPs are generated. I have
searched the documentation but there does not seem to be any compiler
option covering NOP generation. Can anyone help?

Here is the C code:

main()
{
;
;
;
;
;
puts("done");
}

lccwin generates NO CODE for an empty statement. I do not know where
you got the idea that an empty statement should generate a NOP

That idea is completely wrong, sorry.

BUT THERE IS SOLUTION:

I can develop a special version FOR YOU that will emit a NOP
when you write an empty statemnt.

Please write to
jacob at jacob dot remcomp dot fr

for pricing...
 
B

Ben Pfaff

jacob navia said:
Le 04/01/11 23:30, Edward Rutherford a écrit :

I can develop a special version FOR YOU that will emit a NOP
when you write an empty statemnt.

A special version of lcc-win will not be a portable solution.
 
J

jacob navia

Le 04/01/11 23:50, Ben Pfaff a écrit :
A special version of lcc-win will not be a portable solution.

Ahhh c'mon Ben, why screw my business?

Besides it is 100 portable, you can copy it in as many machines as you
like, and if you put it in a USB key, you can carry it around anywhere.

100% PORTABLE!
 
E

Edward Rutherford

Ben said:
A special version of lcc-win will not be a portable solution.

True - perhaps C needs a new nop keyword to be added.

Jacob is obviously joking about "pricing" - this would be a very easy
fix, only a few minutes work, and I would suggest having a compile time
option so that all users of lcc can choose how they want C empty
statements to be translated, in case some of them prefer the old
behaviour.
 
K

Keith Thompson

Edward Rutherford said:
I am trying to write code that includes a certain number of NOPs in the
generated machine code, I would like to do it portably so without using
inline asm.

On lccwin, even without optimisations, no NOPs are generated. I have
searched the documentation but there does not seem to be any compiler
option covering NOP generation. Can anyone help?

Here is the C code:

main()
{
;
;
;
;
;
puts("done");
}

Here is the generated assembly - as you can see, the 5 NOPs are missing.
[snip]

An empty statement does not specify the generation of any particular
machine instruction.

In fact, *no* C statement specifies the generation of any particular
machine instruction. The job of a compiler is to generate code
that implements the semantics of your C program, not to generate
any particular CPU instructions. (C has been called a "portable
assembler", but it really isn't.)

If you want to generate a particular number of NOP instructions
(I won't ask why), you'll have to use some implementation-specific
method. I think lcc-win supports some sort of non-standard inline
asm; you said you don't want to use inline asm, but that's pretty
much your best option. No portable C solution exists.

Followups redirected.
 
J

jacob navia

Le 04/01/11 23:54, Edward Rutherford a écrit :
True - perhaps C needs a new nop keyword to be added.

#define __nop__ _asm("nop")

I can't understand why inline asm is not used here...
 
R

robertwessel2

True - perhaps C needs a new nop keyword to be added.

Jacob is obviously joking about "pricing" - this would be a very easy
fix, only a few minutes work, and I would suggest having a compile time
option so that all users of lcc can choose how they want C empty
statements to be translated, in case some of them prefer the old
behaviour.


Perhaps a __nop intrinsic (which, somewhat bizarrely, has been
implemented on a fair number of compilers), would be a better idea.
(Tongue-sort-of-in-cheek)
 
B

BartC

I am trying to write code that includes a certain number of NOPs in the
generated machine code, I would like to do it portably so without using
inline asm.

I'm not sure the concept of Nop is even portable...

Did you have a particular machine instruction in mind, for every conceivable
machine? If not then it probably doesn't matter what instructions are
generated; maybe you can even use some actual C code.
 
G

glen herrmannsfeldt

I'm not sure the concept of Nop is even portable...

Some machines have more than one...
Did you have a particular machine instruction in mind, for every conceivable
machine? If not then it probably doesn't matter what instructions are
generated; maybe you can even use some actual C code.

The favorite problem when writing benchmarks, of making sure that
the compiler doesn't optimize away the operations. How about

i += 0;

i *= 1;

i /= 1;

with no optimization, how many compilers will generate the
specified operation?

-- glen
 
B

BartC

glen herrmannsfeldt said:
The favorite problem when writing benchmarks, of making sure that
the compiler doesn't optimize away the operations. How about

i += 0;

i *= 1;

i /= 1;

with no optimization, how many compilers will generate the
specified operation?

I was going to say my compiler, but I've just tried it, and no code! (A bit
of a surprise because I thought it did no useful optimisations at all, let
alone for silly, unlikely code.)

But it does generate code for:

i;

It would be difficult I think to find a C expression that doesn't access
memory, sets no flags, generates a single byte of code, and behaves
consistently across machines; but depending on exactly why these no-ops are
needed, that may or may not be important.
 
B

Ben Pfaff

BartC said:
It would be difficult I think to find a C expression that doesn't
access memory, sets no flags, generates a single byte of code, and
behaves consistently across machines; but depending on exactly why
these no-ops are needed, that may or may not be important.

The "single byte of code" part is impossible, because some
architectures have fixed-length instructions that are wider than
one byte.
 
G

glen herrmannsfeldt

The "single byte of code" part is impossible, because some
architectures have fixed-length instructions that are wider than
one byte.

For IA32 the NOP instruction, X'90', is in the position where

XCHG AX,AX

would be, and presumably is generated for that case.

The only other one that I happen to remember is for S/360
(and successors), where there is a four byte NOP, and two
byte NOPR. (That is, RX form and RR form.) Those are the
two forms of conditional branch with the mask set to zero.
They have an operand which is an address (RX), or register (RR).

-- glen
 
R

robertwessel2

For IA32 the NOP instruction, X'90', is in the position where

  XCHG AX,AX

would be, and presumably is generated for that case.


These days Intel defines single instruction x86 NOPs from 1 to 9 bytes
in length. The longer forms actually code memory references, but are
guaranteed not to actually access that memory.

The only other one that I happen to remember is for S/360
(and successors), where there is a four byte NOP, and two
byte NOPR.  (That is, RX form and RR form.)  Those are the
two forms of conditional branch with the mask set to zero.
They have an operand which is an address (RX), or register (RR).


These days you can code a Branch Relative Condition Long, and get a
six byte NOP.

What does it say about the longevity of ISAs when the architects have
found time define additional no-operation instructions?

In the same vein, both Intel and IBM have defined explicit undefined
instructions. Intel even gave it a mnemonic.
 
G

glen herrmannsfeldt

These days Intel defines single instruction x86 NOPs from 1 to 9 bytes
in length. The longer forms actually code memory references, but are
guaranteed not to actually access that memory.

Hmm, my book doesn't have those. Well, I use the IA32 part of
the Itanium reference as an IA32 reference. It should be right, though.

(snip on S/360 NOP and NOPR)
These days you can code a Branch Relative Condition Long, and get a
six byte NOP.

It seems that there is now JNOP and JLNOP as assembler mnemonics
for not branching with BRC and BRCL. Note that all four have an
operand, though it could be zero if not otherwise needed.

Then there is the PDP-10. I am not sure which instruction is
the official NOP, but there are the JUMP and SKIP with the
descriptions "Don't JUMP" and "Don't SKIP", respectively.
What does it say about the longevity of ISAs when the architects have
found time define additional no-operation instructions?
In the same vein, both Intel and IBM have defined explicit undefined
instructions. Intel even gave it a mnemonic.

and IBM has the DIAGNOSE instruction, specificially implementation
dependent, and with no mnemonic defined. As it used with VM,
I believe that there is an assembler macro to generate one.

-- glen
 
R

robertwessel2

(snip, I wrote)
and IBM has the DIAGNOSE instruction, specificially implementation
dependent, and with no mnemonic defined.  As it used with VM,
I believe that there is an assembler macro to generate one.


"DIAG" actually. A problem for the assembler is that Diagnose doesn't
even have a defined format. VM's usage is RS, but other than being a
four byte instruction, nothing defined at the hardware level. And I
don't think the macro is there in VSE or MVS, or at least it didn't
used to be there. Our supervisor mode code that issues Diagnoses to
VM from supervisor mode in those OS's uses our own macro (although
that's been that either been unchanged or copied from old code for the
last couple of decades).
 
B

BartC

Then there is the PDP-10.

Not exactly common these days...

I am not sure which instruction is
the official NOP, but there are the JUMP and SKIP with the
descriptions "Don't JUMP" and "Don't SKIP", respectively.

There was SKIPN and (iirc) JUMPN. SKIPN did seem a bit pointless, but it was
just a consequence of a particular pattern of condition codes.

In the same way many processors will have the apparently pointless
instructions MOV Rn,Rn, or EXCH Rn,Rn, otherwise there would be an untidy
hole in the opcode map.

As I said, there are various ways of constructing a no-op instruction, so
which one should be generated from an empty C statement? (Although this is
the first I've heard of such a statement having to generate a NOP
instruction.)
 

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

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top