I'm writing up a benchmark to compare the movbe
operation against mov; bswap
to find out which is faster.
I used to write "extern C function ..."
up until now, but for specific reasons i can't install NASM or any additional software besides gcc on the target system, so I'm stuck with inline assembly.
I wrote this code:
#include <time.h>
#include <stdio.h>
void movBeBenchmark(void);
void movBswapBenchmark(void);
/*
benchmarks the movbe instruction with ecx as counter
uses easy to read values, for ez debugging
(check whether values are reversed)
*/
void movBeBenchmark(){
//bring the stack into a well defined format, initialize counter
__asm volatile( ".intel_syntax noprefix\n"
"mov [ebp-4], 11112222\n"
"mov [ebp-8], 33334444\n"
"mov [ebp-12], 55556666\n"
"mov [ebp-16], 77778888\n"
"mov [ebp-20], 9999aaaa\n"
"mov [ebp-24], bbbbcccc\n"
"mov [ebp-28], ddddffff\n"
"mov [ebp-32], 12345678\n"
"mov ecx, 10000\n"
); //10K loops should suffice for benchmarking
//start a timer for benchmarking
float startTime = (float)clock()/CLOCKS_PER_SEC;
//TODO: debug this and check values!!!
__asm volatile( ".intel_syntax noprefix\n"
"LOOP: \n"
"movbe r8, [ebp-4]\n"
"movbe r9, [ebp-8]\n"
"movbe r10, [ebp-12]\n"
"movbe r11, [ebp-16]\n"
"movbe r12, [ebp-20]\n"
"movbe r13, [ebp-24]\n"
"movbe r14, [ebp-28]\n"
"movbe r15, [ebp-32]\n"
"movbe [ebp-4], r8\n"
"movbe [ebp-8], r9\n"
"movbe [ebp-12], r10\n"
"movbe [ebp-16], r11\n"
"movbe [ebp-20], r12\n"
"movbe [ebp-24], r13\n"
"movbe [ebp-28], r14\n"
"movbe [ebp-32], r15\n"
"loop @LOOP\n"
);
//stop timer
float endTime = (float)clock()/CLOCKS_PER_SEC;
fprintf(stdout, "Function took %.6f units to execution!\n", startTime - endTime);
}
int main(){
fprintf(stdout, "MovBe Benchmark\n");
movBeBenchmark();
return 0;
}
However, I am getting a lot of errors and can't make out why these operations are failing. My output is
gcc main.c -o benchmark
main.c: Assembler messages:
main.c:16: Error: ambiguous operand size for `mov'
main.c:17: Error: ambiguous operand size for `mov'
main.c:18: Error: ambiguous operand size for `mov'
main.c:19: Error: ambiguous operand size for `mov'
main.c:20: Error: junk `aaaa' after expression
main.c:21: Error: operand size mismatch for `mov'
main.c:22: Error: operand size mismatch for `mov'
main.c:23: Error: ambiguous operand size for `mov'
/tmp/cctHuXIm.s:35: Error: operand type mismatch for `cvtsi2ss'
/tmp/cctHuXIm.s:36: Error: junk `(%rip)' after expression
/tmp/cctHuXIm.s:38: Error: junk `(%rbp)' after expression
main.c:49: Error: bad expression
main.c:49: Error: junk `LOOP' after expression
/tmp/cctHuXIm.s:64: Error: operand type mismatch for `cvtsi2ss'
/tmp/cctHuXIm.s:65: Error: junk `(%rip)' after expression
/tmp/cctHuXIm.s:67: Error: junk `(%rbp)' after expression
/tmp/cctHuXIm.s:68: Error: junk `(%rbp)' after expression
/tmp/cctHuXIm.s:69: Error: junk `(%rbp)' after expression
/tmp/cctHuXIm.s:71: Error: junk `(%rip)' after expression
/tmp/cctHuXIm.s:72: Error: no such instruction: `movl $.LC1,%esi'
/tmp/cctHuXIm.s:73: Warning: mnemonic suffix used with `mov'
/tmp/cctHuXIm.s:73: Warning: NOTE: Such forms are deprecated and will be rejected by a future version of the assembler
/tmp/cctHuXIm.s:74: Error: no such instruction: `movl $1,%eax'
/tmp/cctHuXIm.s:92: Warning: mnemonic suffix used with `push'
/tmp/cctHuXIm.s:95: Warning: mnemonic suffix used with `mov'
/tmp/cctHuXIm.s:97: Error: junk `(%rip)' after expression
/tmp/cctHuXIm.s:98: Warning: mnemonic suffix used with `mov'
/tmp/cctHuXIm.s:99: Error: no such instruction: `movl $16,%edx'
/tmp/cctHuXIm.s:100: Error: no such instruction: `movl $1,%esi'
/tmp/cctHuXIm.s:101: Error: no such instruction: `movl $.LC2,%edi'
/tmp/cctHuXIm.s:104: Error: no such instruction: `movl $0,%eax'
/tmp/cctHuXIm.s:105: Warning: mnemonic suffix used with `pop'
Of course I already fiddled around with the operations, tried using DWORD PTRs and googled for the errors. This is where my luck ran out.
I seem to have problems with the mov instruction and also with the LOOP label. However, this should be valid x86 code, shouldn't it? Why can't my gcc just inline these operations?
Pls help and elaborate
It's a really bad idea to switch syntaxes in inline assembly. Remove the syntax directive and instead compile with -masm=intel
. The errors you get are because gcc uses AT&T syntax for its own code, but you just switched to Intel syntax, confusing the assembler.
There's more wrong with your code:
m
(memory) constraint0x
mov [ebp-4], 11112222
. This is done by adding something like dword ptr
to the appropriate place.It may be best for your application to just place the assembly code into an assembly file and include that file into the build. Gcc uses the GNU assembler and can pass assembly files to the assembler if asked to compile them. No extra software needs to be installed.