if don't want overhead needed call strcmp, compare strings short string literals way described in following code example:
#ifdef little_endian //little-endian-addressing #define bytesasdword_m(a, b, c, d)\ ((ulong) ((a) | ((b) << 8) | ((ulong) (c) << 16) | ((ulong) (d) << 24))) #define bytesasword_m(a, b)((ushort) ((a) | ((b) << 8))) #else //little_endian //little-endian-addressing #define bytesasdword_m(a, b, c, d)\ ((ulong) ((d) | ((c) << 8) | ((b) << 16) | ((a) << 24))) #define bytesasword_m(a, b) ((ushort) ((b) | ((a) << 8))) #endif //little_endian //little-endian-addressing bool abscompare(char* chr_p) //compare string "abs" { if (*((ulong*) &chr_p[1]) == bytesasdword_m('a', 'b', 's', '\0')) return true; return false; }
gcc compiles example long compile without optimization options enabled. optimization enabled warning:
"dereferencing type-punned pointer break strict-aliasing rules"
even optimizing -o3 doesn't result in effective code example illustrates:
//abstest.c #include <string.h> typedef unsigned long ulong; typedef unsigned short ushort; #if byte_order == little_endian //little-endian-addressing #define bytesasdword_m(a, b, c, d)\ ((ulong) ((a) | ((b) << 8) | ((ulong) (c) << 16) | ((ulong) (d) << 24))) #define bytesasword_m(a, b)((ushort) ((a) | ((b) << 8))) #else //byte_order == little_endian //little-endian-addressing #define bytesasdword_m(a, b, c, d)\ ((ulong) ((d) | ((c) << 8) | ((b) << 16) | ((a) << 24))) #define bytesasword_m(a, b) ((ushort) ((b) | ((a) << 8))) #endif //byte_order == little_endian //little-endian-addressing int abscompare1(char* chr_p) { return *(ulong*) chr_p == bytesasdword_m('a', 'b', 's', '\0'); } int abscompare2(char* chr_p) { return strcmp(chr_p, "abs"); } int main(int argc __attribute__((unused)), char ** argv) { int i; int j; = abscompare1(argv[0]); j = abscompare2(argv[0]); return + j; }
objdump -d -mintel abstest:
080483d0 <abscompare1>: 80483d0: 55 push ebp 80483d1: 89 e5 mov ebp,esp 80483d3: 8b 45 08 mov eax,dword ptr [ebp+0x8] 80483d6: 5d pop ebp 80483d7: 81 38 61 62 73 00 cmp dword ptr [eax],0x736261 80483dd: 0f 94 c0 sete al 80483e0: 0f b6 c0 movzx eax,al 80483e3: c3 ret 080483f0 <abscompare2>: 80483f0: 55 push ebp 80483f1: 0f b6 0d 5c 85 04 08 movzx ecx,byte ptr ds:0x804855c 80483f8: 89 e5 mov ebp,esp 80483fa: 8b 55 08 mov edx,dword ptr [ebp+0x8] 80483fd: 0f b6 02 movzx eax,byte ptr [edx] 8048400: 29 c8 sub eax,ecx 8048402: 75 2b jne 804842f <abscompare2+0x3f> 8048404: 0f b6 42 01 movzx eax,byte ptr [edx+0x1] 8048408: 0f b6 0d 5d 85 04 08 movzx ecx,byte ptr ds:0x804855d 804840f: 29 c8 sub eax,ecx 8048411: 75 1c jne 804842f <abscompare2+0x3f> 8048413: 0f b6 42 02 movzx eax,byte ptr [edx+0x2] 8048417: 0f b6 0d 5e 85 04 08 movzx ecx,byte ptr ds:0x804855e 804841e: 29 c8 sub eax,ecx 8048420: 75 0d jne 804842f <abscompare2+0x3f> 8048422: 0f b6 42 03 movzx eax,byte ptr [edx+0x3] 8048426: 0f b6 15 5f 85 04 08 movzx edx,byte ptr ds:0x804855f 804842d: 29 d0 sub eax,edx 804842f: 5d pop ebp 8048430: c3 ret
is there possibility compare short literal directly without detour of embedding chr_p union, because want compare chr_p @ arbitrary indices "&chr_p[1]"?
no there not. aware compiler use knowledge strcmp
? achieve (removing call overhead) without having resort type-punning in source. these kind of code transformations done in code generator after compiler has taken benefit alias analysis.
if use gcc -o3
compile following program, there no call strcmp
found.
#include <string.h> int main(int argc, char ** argv) { return strcmp(argv[0], "abs"); }
my x86 assembly example looked (gcc version 4.3.2 (debian 4.3.2-1.1)) (i know it's old):
main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %ecx movl 4(%ecx), %eax movl (%eax), %edx movzbl (%edx), %eax subl $97, %eax jne .l2 movzbl 1(%edx), %eax subl $98, %eax jne .l2 movzbl 2(%edx), %eax subl $115, %eax jne .l2 movzbl 3(%edx), %eax .l2: popl %ecx popl %ebp leal -4(%ecx), %esp ret
basically strcmp
has been inlined , unrolled. of course highly depends on code generator target. if not evolved enough yet, may still generate strcmp
. still makes wonder if should burden ugly code, if maybe code generator support later .. when still stuck code.
Comments
Post a Comment