Created
March 17, 2019 18:34
-
-
Save JohnLaTwC/e9a2665ce9ae0b460fc4d2f676390f85 to your computer and use it in GitHub Desktop.
Fibonacci contest winner
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ULONG __declspec(naked) CalcFibMT5 (int dwFibNum) | |
{ | |
// dwFibNum is passed at esp-4 | |
// Result must be returned in eax | |
__asm | |
{ | |
// start pushing working registers ecx, ebx. eax is clobbered | |
push ecx | |
mov ecx, round_finish | |
// retrieve dwFibNum into ecx from stack | |
mov eax, esp | |
add eax, 8 // 4 plus a ULONG push | |
mov eax, [eax] // this is dwFibNum | |
// work registers: ebx, eax. Final result always ends up in eax | |
push ebx | |
// register-register ADD instruction is 2 bytes | |
shl eax, 1 // each round is 2 bytes, so NOW this is how many instructions we want to execute | |
sub ecx, eax // walk backward as many instructions as we need | |
// push our initial state for fib(1) and fib(2) | |
mov ebx, 1 // load with initial state (eax = 1) | |
mov eax, 1 // our initial answer | |
jmp ecx // and jump to our computation | |
// round_start: | |
// 48 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 46 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 44 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 42 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 40 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 38 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 36 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 34 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 32 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 30 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 28 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 26 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 24 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 22 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 20 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 18 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 16 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 14 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 12 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 10 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 8 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 6 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// 4 | |
add ebx, eax // result of 1st round stored in ebx | |
add eax, ebx // result of 2nd round stored in eax | |
// oh, what a tangled web we weave | |
// when first we practice to deceive | |
// this is NEVER executed as 4 noops | |
// it is mov ecx, 0x90908bff | |
// or mov esi, esi | |
// depending on where you jump into it | |
_emit 0xb9 | |
_emit 0x90 | |
_emit 0x90 | |
_emit 0x8b | |
round_finish: | |
_emit 0xf6 | |
// the 'straightforward' version | |
// 2 | |
// nop | |
// nop | |
// 1 | |
// nop | |
// nop | |
// result in eax | |
pop ebx | |
pop ecx | |
ret 4 | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment