[kohlrak@kohlrak-server temp]$ cat main.cpp #include #include template T swap_endian(T u) { //static_assert (CHAR_BIT == 8, "CHAR_BIT != 8"); //Totally unnecessary. union { T u; unsigned char u8[sizeof(T)]; } source, dest; source.u = u; for (T k = 0; k < sizeof(T); k++) dest.u8[k] = source.u8[sizeof(T) - k - 1]; return dest.u; } int main(int argc, char **argv){ int le = atoi(argv[1]), be; //For the sake of example, we'll just assume the user will send us the correct number of params. be=swap_endian(le); printf("LE: 0x%08x\nBE: 0x%08x\n", le, be); return 0; } [kohlrak@kohlrak-server temp]$ ./a.out 328328 LE: 0x00050288 BE: 0x88020500 [kohlrak@kohlrak-server temp]$ g++ main.cpp -S -masm=intel -O9 [kohlrak@kohlrak-server temp]$ cat main.s .file "main.cpp" .intel_syntax noprefix .section .rodata.str1.1,"aMS",@progbits,1 .LC0: .string "LE: 0x%08x\nBE: 0x%08x\n" .section .text.startup,"ax",@progbits .globl main main: .LFB27: #begin variable preserving lea ecx, [esp+4] and esp, -16 #create 2 int variables (taking advantage of it being aligned to use the faster and instruction) push DWORD PTR [ecx-4] push ebp mov ebp, esp #end variable preserving push ebx #begin atoi(argv[1]). note: the function atoi is actually here, rather than calling atoi. push ecx mov eax, DWORD PTR [ecx+4] sub esp, 4 push 10 push 0 push DWORD PTR [eax+4] call strtol #end atoi(argv[1]), note return value is in eax register AKA beginning of swap_endian(le) mov ecx, eax #put result of atoi(argv[1]) into ecx register. xor edx, edx #empty edx register (RAM efficient) mov ebx, eax #put result of atoi(argv[1]) into ebx register. shr ecx, 24 #performing C++'s >>24 on ecx sal ebx, 24 #performing C++ <<24 on ebx. add esp, 12 #deleting the variables used by atoi(argv[1]). mov dl, cl #moving the first byte of ecx to edx (aka edx=ecx&0xFF) mov ecx, eax #moving that return from atoi(argv[1]) into ecx shr ecx, 16 #ecx>>16 mov dh, cl #moving the result from that into the second byte of edx movzx ecx, ah #moving the second byte of the return of atoi(argv[1]) to ecx sal ecx, 16 #ecx<<16 movzx edx, dx #edx=edx&0xFFFF; or edx, ecx #edx|=ecx or edx, ebx #edx|=ebx AKA end of swap_endian(le), result in edx push edx #begin printf("LE: 0x%08x\nBE: 0x%08x\n", le, be); push eax push OFFSET FLAT:.LC0 call printf add esp, 16 lea esp, [ebp-8] xor eax, eax #set eax to 0 pop ecx #end printf("LE: 0x%08x\nBE: 0x%08x\n", le, be); pop ebx pop ebp lea esp, [ecx-4] #restore preserved registers and variables ret #return; NOTE: eax is the register that holds return values, which is 0.