* Help! Program crashed when call the inline assembly function continuously @ 2010-03-31 14:18 spark.z 2010-03-31 14:56 ` Cedric Roux 2010-04-07 14:46 ` Ian Lance Taylor 0 siblings, 2 replies; 9+ messages in thread From: spark.z @ 2010-03-31 14:18 UTC (permalink / raw) To: gcc-help Eclipse + gcc-4.4.1, compiled the program with optimization flag -O2 I wrote a inline function with inlined assembly void pincrement(int* target) { __asm__ __volatile__ ("pushl %eax"); __asm__ __volatile__ ("lock ; incl (%%eax)" ::"a"(target)); __asm__ __volatile__ ("popl %eax"); } and call it in the main function like: int main() { static int my_an = 0; pincrement(&my_an); pincrement(&my_an); pincrement(&my_an); printf("my_an is %d\n",my_an); } It crashed when run the app. So I check the assembly code of the app. The complier translate the three pincrement call become: push eax mov eax, offset dword_474048 lock inc dword ptr [eax] pop eax push eax lock inc dword ptr [eax] pop eax push eax lock inc dword ptr [eax] pop eax It only has one "mov eax, offset dword_474048" sentence in it. How can I tell the gcc complier to inline the whole assembly function three times completely? :working: -- View this message in context: http://old.nabble.com/Help%21-Program-crashed-when-call-the-inline-assembly-function-continuously-tp28094526p28094526.html Sent from the gcc - Help mailing list archive at Nabble.com. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Help! Program crashed when call the inline assembly function continuously 2010-03-31 14:18 Help! Program crashed when call the inline assembly function continuously spark.z @ 2010-03-31 14:56 ` Cedric Roux 2010-03-31 21:24 ` spark.z 2010-04-07 14:46 ` Ian Lance Taylor 1 sibling, 1 reply; 9+ messages in thread From: Cedric Roux @ 2010-03-31 14:56 UTC (permalink / raw) To: spark.z; +Cc: gcc-help spark.z wrote: > Eclipse + gcc-4.4.1, compiled the program with optimization flag -O2 > I wrote a inline function with inlined assembly > void pincrement(int* target) > { > __asm__ __volatile__ ("pushl %eax"); > __asm__ __volatile__ ("lock ; incl (%%eax)" ::"a"(target)); > __asm__ __volatile__ ("popl %eax"); > } void pincrement(int* target) { __asm__ __volatile__ ("pushl %%eax"); __asm__ __volatile__ ("lock ; incl (%%eax)" ::"a"(target)); __asm__ __volatile__ ("popl %%eax":::"eax"); } seems to do the trick. (the third asm statement adds eax in the clobber list) (and I also add to write %%eax instead of your %eax). You should tell gcc what your asm statement modifies. Here, the pop modifies eax. But even the first asm statement modifies the stack and we don't tell gcc, but does that matter? I don't know. And the second also modifies *target, maybe we should tell gcc too here. Anyway, you've got the idea. Maybe someone else will have a better answer. And you should read the gcc documentation about "Extended Asm." ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Help! Program crashed when call the inline assembly function continuously 2010-03-31 14:56 ` Cedric Roux @ 2010-03-31 21:24 ` spark.z 2010-04-01 8:40 ` Cedric Roux 0 siblings, 1 reply; 9+ messages in thread From: spark.z @ 2010-03-31 21:24 UTC (permalink / raw) To: gcc-help Many thanks to you, the app works correctly according to your sulotion:handshake: But I am confused with another situation as below (static int my_an = 0 ===> int my_an = 0) int main() { int my_an = 0; pincrement(&my_an); pincrement(&my_an); pincrement(&my_an); printf("my_an is %d\n",my_an); } it show me a wrong result => "my_an is 0". Is there any differences between the local variable and the static variable as the param? :confused: -- View this message in context: http://old.nabble.com/Help%21-Program-crashed-when-call-the-inline-assembly-function-continuously-tp28094526p28097083.html Sent from the gcc - Help mailing list archive at Nabble.com. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Help! Program crashed when call the inline assembly function continuously 2010-03-31 21:24 ` spark.z @ 2010-04-01 8:40 ` Cedric Roux 2010-04-01 13:38 ` spark.z 0 siblings, 1 reply; 9+ messages in thread From: Cedric Roux @ 2010-04-01 8:40 UTC (permalink / raw) To: spark.z; +Cc: gcc-help spark.z wrote: > Many thanks to you, the app works correctly according to your > sulotion:handshake: > > But I am confused with another situation as below (static int my_an = 0 ===> > int my_an = 0) > int main() > { > int my_an = 0; > pincrement(&my_an); > pincrement(&my_an); > pincrement(&my_an); > printf("my_an is %d\n",my_an); > } > > it show me a wrong result => "my_an is 0". Is there any differences between > the local variable and the static variable as the param? :confused: If i write: void pincrement(long* target) { __asm__ __volatile__ ("pushq %rax"); __asm__ __volatile__ ("lock ; incb (%%rax)" :"=m" (*target) :"a"(target), "m" (*target)); __asm__ __volatile__ ("popq %%rax":::"rax"); } (64b, I'm on a 64b, adapt to your needs, it's more or less the same) some code is produced. But it is compiled to (just the beginning): 0x0000000000400540 <main+0>: sub $0x18,%rsp 0x0000000000400544 <main+4>: movq $0xa,0x8(%rsp) 0x000000000040054d <main+13>: push %rax 0x000000000040054e <main+14>: lea 0x8(%rsp),%rdx 0x0000000000400553 <main+19>: mov %rdx,%rax 0x0000000000400556 <main+22>: lock incb (%rax) 0x0000000000400559 <main+25>: pop %rax See what's wrong? the first asm statement of pincrement modifies the stack pointer. gcc doesn't know that. The second asm statement loads target by doing "lea 0x8(%rsp), %rdx" problem is: rsp has changed, so 0x8(%rsp) does not point anymore to target. So one answer to your question is: add "=m" and "m" to your list of input/output (I don't know which one is absolutely necessary, maybe both). (And read the gcc documentation on "extended asm," it's all explained.) But! Your code still won't work because of the first push which modifies the stack pointer. gcc doesn't know and on the second asm statement uses the old value. Depending on how gcc will behave, it will work or not (it may access target through ebp instead of esp for example, which will work). I don't know if there is an answer to your problem. Maybe there is something to add in the clobber list to tell the stack pointer moved, and moved of xxx bytes in this or that direction. Anyway, why the push/pop? gcc will know eax is modified since it's used as input parameter in the asm statement. It will adapt itself automatically. Or do you plan to use pincrement in another context where you absolutely need eax not to change inside of pincrement? (in which case, maybe it's better to write it directly in assembly). ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Help! Program crashed when call the inline assembly function continuously 2010-04-01 8:40 ` Cedric Roux @ 2010-04-01 13:38 ` spark.z 2010-04-01 13:52 ` Cedric Roux 0 siblings, 1 reply; 9+ messages in thread From: spark.z @ 2010-04-01 13:38 UTC (permalink / raw) To: gcc-help The app works fine if I add the volatile prefix before the variable declaration. inline void pincrement(volatile int* target) { __asm__ __volatile__ ("pushl %%eax":::); __asm__ __volatile__ ("lock ; incl (%%eax)" :"=m"(target):"a"(target)); __asm__ __volatile__ ("popl %%eax":::"eax"); } inline void pdecrement(volatile int* target) { __asm__ __volatile__ ("pushl %%eax":::); __asm__ __volatile__ ("lock ; decl (%%eax)" :"=m"(target):"a"(target)); __asm__ __volatile__ ("popl %%eax":::"eax"); } int main() { volatile int my_an = 0; pincrement(&my_an); pincrement(&my_an); pincrement(&my_an); pdecrement(&my_an); printf("my_an is %d\n",my_an); return 0; } -- View this message in context: http://old.nabble.com/Help%21-Program-crashed-when-call-the-inline-assembly-function-continuously-tp28094526p28107792.html Sent from the gcc - Help mailing list archive at Nabble.com. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Help! Program crashed when call the inline assembly function continuously 2010-04-01 13:38 ` spark.z @ 2010-04-01 13:52 ` Cedric Roux 2010-04-08 13:01 ` spark.z 0 siblings, 1 reply; 9+ messages in thread From: Cedric Roux @ 2010-04-01 13:52 UTC (permalink / raw) To: spark.z; +Cc: gcc-help spark.z wrote: > The app works fine if I add the volatile prefix before the variable > declaration. > > inline void pincrement(volatile int* target) > { > __asm__ __volatile__ ("pushl %%eax":::); > __asm__ __volatile__ ("lock ; incl (%%eax)" :"=m"(target):"a"(target)); > __asm__ __volatile__ ("popl %%eax":::"eax"); > } > > inline void pdecrement(volatile int* target) > { > __asm__ __volatile__ ("pushl %%eax":::); > __asm__ __volatile__ ("lock ; decl (%%eax)" :"=m"(target):"a"(target)); > __asm__ __volatile__ ("popl %%eax":::"eax"); > } > > > int main() { > volatile int my_an = 0; > pincrement(&my_an); > pincrement(&my_an); > pincrement(&my_an); > pdecrement(&my_an); > printf("my_an is %d\n",my_an); > return 0; > } > try to compile like: gcc myprog.c -fomit-frame-pointer does it still work? (not for me with gcc 3.3.5, I have a segmentation fault) your "push eax" statements are not correct because you don't tell gcc they modify the stack pointer. It works because you are lucky, but your code is broken. One day or another it will crash. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Help! Program crashed when call the inline assembly function continuously 2010-04-01 13:52 ` Cedric Roux @ 2010-04-08 13:01 ` spark.z 0 siblings, 0 replies; 9+ messages in thread From: spark.z @ 2010-04-08 13:01 UTC (permalink / raw) To: gcc-help Thank you for reminding me of this potential risk. :handshake: -- View this message in context: http://old.nabble.com/Help%21-Program-crashed-when-call-the-inline-assembly-function-continuously-tp28094526p28178214.html Sent from the gcc - Help mailing list archive at Nabble.com. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Help! Program crashed when call the inline assembly function continuously 2010-03-31 14:18 Help! Program crashed when call the inline assembly function continuously spark.z 2010-03-31 14:56 ` Cedric Roux @ 2010-04-07 14:46 ` Ian Lance Taylor 2010-04-08 13:04 ` spark.z 1 sibling, 1 reply; 9+ messages in thread From: Ian Lance Taylor @ 2010-04-07 14:46 UTC (permalink / raw) To: spark.z; +Cc: gcc-help "spark.z" <spark.yj.zhao@gmail.com> writes: > void pincrement(int* target) > { > __asm__ __volatile__ ("pushl %eax"); > __asm__ __volatile__ ("lock ; incl (%%eax)" ::"a"(target)); > __asm__ __volatile__ ("popl %eax"); > } Besides all the other answers, don't write your asm code like this. Put all the assembler code in a single asm statement rather than using separate asm statements. In any case the pushl and popl appear to be unnecessary here. Also you should look into the __sync_fetch_and_add and __sync_add_and_fetch builtin functions. Ian ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Help! Program crashed when call the inline assembly function continuously 2010-04-07 14:46 ` Ian Lance Taylor @ 2010-04-08 13:04 ` spark.z 0 siblings, 0 replies; 9+ messages in thread From: spark.z @ 2010-04-08 13:04 UTC (permalink / raw) To: gcc-help Many thanks to you for this new solution. -- View this message in context: http://old.nabble.com/Help%21-Program-crashed-when-call-the-inline-assembly-function-continuously-tp28094526p28178271.html Sent from the gcc - Help mailing list archive at Nabble.com. ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2010-04-08 13:04 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2010-03-31 14:18 Help! Program crashed when call the inline assembly function continuously spark.z 2010-03-31 14:56 ` Cedric Roux 2010-03-31 21:24 ` spark.z 2010-04-01 8:40 ` Cedric Roux 2010-04-01 13:38 ` spark.z 2010-04-01 13:52 ` Cedric Roux 2010-04-08 13:01 ` spark.z 2010-04-07 14:46 ` Ian Lance Taylor 2010-04-08 13:04 ` spark.z
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).