GCC对内联汇编真是弱这算是bug么?

GCC 4.92
默认优化 -Os
dwecx = 0x6ccc7ecb;
dwcall = dwso + 0x123456;
asm(“mov %1,%%ecx;call %0”::“m”(dwcall),“m”(dwecx));
dwcall = dwso + 0x777777;
asm(“pushl $0;mov %1,%%ecx;call %0”::“m”(dwcall),“m”(dwecx));

编译后的反汇编代码
lea edx, dword ptr ds:[eax+0x123456]
sub esp, 0x10
mov dword ptr ss:[esp+0x1C], eax
mov dword ptr ss:[esp+0x18], edx
mov ecx, dword ptr ss:[esp+0x1C]
call dword ptr ss:[esp+0x18]
add ebx, 0x777777
mov dword ptr ss:[esp+0x18], ebx
push 0x0
mov ecx, dword ptr ss:[esp+0x1C]
call dword ptr ss:[esp+0x18]
add esp, 0x28
pop ebx
retn

看红色代码,我 push 0 以后,esp-4 了,他传的局部变量地址没变,这样程序肯定是错的,应该是
push 0x0
mov ecx, dword ptr ss:[esp+0x20]
call dword ptr ss:[esp+0x1c]
:nauseated_face: 搞得我途血啊啊啊啊!!!

关闭优化,他会默认使用 ebp-XXX,这样就不会出现这个错误了

唠叨一句,这 AT&T 语法的汇编看得我蛋疼,眼都花了,要是能支持 intel 格式的汇编语法该多好,简洁干净

再看
mov dword ptr ss:[esp+0xC], 0x40 ; |
mov dword ptr ss:[esp+0x8], 0x1000 ; |
mov dword ptr ss:[esp+0x4], 0x95D0 ; |
mov dword ptr ss:[esp], 0x0 ; |
我承认这样传参数调用 api 速度快,但是我关闭了优化你好歹也把 push 体现出来啊,我保存寄存器值用的 push %eax,丫自作聪明把我保存的数据直接 mov esp 抹掉了!!! :nauseated_face:

个人感觉内联汇编的时候就不用开自动优化了吧.

至于 intel 语法, 其实可以把整个函数写在 nasm 里面在用 C 去调用嘛, 这样就爽得多.
手动指定 _cdecl 就应该不会把 push 弄没了.