[kohlrak@kohlrak-server temp]$ cat main.cpp
#include <stdio.h>
#include <stdlib.h>
template <typename T>
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<int>(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.
Comments