Thursday, December 4, 2014

Adding upper towards upwards

                            On this post I changed the program so that it brings the gcd of every set of numbers and adds them together,and also performs no-trace-coding which means we save the registers and restore them so it's like the procedure that changed them was never called.

Here's my program:

.model flat, c
.stack 100h

; gcd(10, 4), gcd(28, 21), gcd(12, 8),
left dword 10, 28, 12
right dword 4, 21, 8


doit proc
  push eax
  push ebx
  push ecx
  xor eax,eax
  xor ecx,ecx
    sub esp,4
    push left[ecx]
push right[ecx]
call gcd
add esp,8
pop ebx
add eax,ebx
add ecx,4
cmp ecx,12
  jl doagain
  pop ecx
  pop ebx
  pop eax

doit endp

gcd proc
push eax
push ebx
push edx
mov eax,[esp + 20]       ; eax is left
mov ebx,[esp + 16]       ; ebx is right
xor edx,edx                   ; zeroing out edx to prevent Integer overflow
div ebx                          ; divides left by right
cmp edx, 0       ; We are done when remainder is zero
je weAreDone

mov eax,ebx       ; we have a new left
mov ebx,edx                 ; our remainder is our new right
jmp again                      ; repeat

; ebx has the greatest common divisor
mov [esp + 24],ebx
pop edx
pop ebx
pop eax


gcd endp


                               You might notice something that wasn't there before,a subtraction by four from the esp. I put that in because when we subtract 4 from the esp it goes up four bytes which is one space up which opens up a little spot,and before that we push eax,ebx,and ecx to the top of the stack. When we do that we are saving the values that those registers have when we first get to doit so that we can restore them later for main. Then we take eax and xor it because we want to use it to add up the gcd's and ecx is our indexer. Then we push left and right to the top of the stack and call gcd placing the return address at the top of the stack. Once we get to gcd we save the registers that we change in gcd for doit and then place left and right in eax and ebx. Once we get to weAreDone after the other parts of the procedure we place the gcd (which is currently in ebx) into that empty slot we created with the subtraction and pop the rest of the registers values in doit back into them,and that's very important because for example: even though eax is used in gcd it's also used in doit as our sum so we have to restore it to the amount that it was in doit or else we're stomping on our sum,and then return to doit leaving right at the top of the stack. Once we get back to doit at the instruction after the call we add 8 to the esp which leaves the return value (our gcd) at the top of the stack. Then we pop it into ebx and add that to eax which in doit is the sum of all of the gcd's. Then when ecx (our indexer) reaches 12 we go down to the pops and restore eax,ebx,and ecx to their original values before we even called doit.     

WELL TTFN,TA TA FOR NOW!!!!!!!!!!!!!!!!!!!!

No comments:

Post a Comment