disable optimization per-function with gcc [SOLVED]

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
pini
Member
Member
Posts: 26
Joined: Wed Oct 18, 2006 5:12 am
Location: Nancy, France

disable optimization per-function with gcc [SOLVED]

Post by pini »

Here is my problem:

I have assembly code that pushes arguments and calls a C function.
The C function looks like :

Code: Select all

void f(int arg) {
  print("some message");
}
This is compiled with -O2 and gcc seems to use the fact that the argument is not used. In fact, it stores the argument to print (the string) at the place where arg is, and so everything is broken upon f return.

This doesn't happen when compiling with -O0, so I'd like to know if there's a way to tell gcc not to optimize anything related to arg (including assuming its stack space is free) ?
Last edited by pini on Tue Jan 22, 2008 7:43 am, edited 1 time in total.
Don't think you can. Know you can.
phire
Posts: 4
Joined: Wed Jan 16, 2008 7:25 pm
Location: Christchruch, New Zealand

Post by phire »

I'm not completely sure, but try declearing arg volatile.
User avatar
proxy
Member
Member
Posts: 108
Joined: Wed Jan 19, 2005 12:00 am
Contact:

Post by proxy »

The problem is not with optimizations, but that with standard C calling convention the caller cleans up the params it pushed onto the stack. One thing you should do is do what linux does for it's "asmlinkage" macro which is an attribute which guarantees C style calling convention.
User avatar
pini
Member
Member
Posts: 26
Joined: Wed Oct 18, 2006 5:12 am
Location: Nancy, France

Post by pini »

phire: I already tried with volatile but didn't help.

proxy: I'll give a try to the __attribute__((regparm(0))) (macro "asmlinkage") this evening
Don't think you can. Know you can.
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: disable optimization per-function with gcc

Post by jal »

pini wrote:This is compiled with -O2 and gcc seems to use the fact that the argument is not used. In fact, it stores the argument to print (the string) at the place where arg is, and so everything is broken upon f return.
I really don't see how 'everything' could be 'broken upon return'. Upon return, the stack location used to store arg should be released anyway. It is temporary. GCC using the location for something else is just the same as you adding a line saying 'arg = (int)(int *)"some message"'. Are you sure there's not something else that's screwed up?


JAL
User avatar
pini
Member
Member
Posts: 26
Joined: Wed Oct 18, 2006 5:12 am
Location: Nancy, France

Post by pini »

It would be the case in the general way, but my calling code is for interrupt handling and looks like this :

Code: Select all

; some stuff
push ds ; save
call my_c_function
pop ds ; restore
; some stuff
As you can see, the argument is not thrown away, as it would normally be the case but reused and that's why I want gcc not to touch it.
Don't think you can. Know you can.
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Post by jal »

pini wrote:As you can see, the argument is not thrown away, as it would normally be the case but reused and that's why I want gcc not to touch it.
You're skating on really thin ice here, as gcc may change any registers in a C function as it sees fit, and may change anything on the stack frame passed to it as it sees fit. You are calling a C-function, but do not adhere to the calling convention for that function.


JAL
User avatar
pini
Member
Member
Posts: 26
Joined: Wed Oct 18, 2006 5:12 am
Location: Nancy, France

Post by pini »

Actually, I change my assembly code to fit the calling convention :

Code: Select all

; some stuff
push ds
push esp
call my_c_func
add esp,4
pop ds
And changed the prototype of the C function do take a int* rather than an int.
Everything works perfectly now.
Don't think you can. Know you can.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

I'd simply have used something like

Code: Select all

push ds
call function
add esp, 4
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
pini
Member
Member
Posts: 26
Joined: Wed Oct 18, 2006 5:12 am
Location: Nancy, France

Post by pini »

Well, I still need the pushed value of ds after the call, so I'll stick with my current hack.
Don't think you can. Know you can.
User avatar
proxy
Member
Member
Posts: 108
Joined: Wed Jan 19, 2005 12:00 am
Contact:

Post by proxy »

is your function supposed to alter the value of ds? If not, then this would do as well (what you currently have will have the net effect of pass-by-reference since you pop the result back into ds).

So the simpler code could be this:

Code: Select all

; some stuff
push ds
push esp
call my_c_func
add esp,8
note that the size pushed on the stack is 32-bit when pushing ds, so when you what to undo it, you need to pop 4 bytes.

proxy[/code]
Post Reply