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