0

I am new to assembly and working with the stack so my knowledge may not be the greatest. I am writing a procedure that accepts two 16-bit operands by value and one operand by OFFSET. The procedure will calculate the sum of the two operands and will store the result into memory at the OFFSET specified. In this assignment, I cant use main and data hence the weird format. After I move the variables into registers for later use I can not find them at any address. Using a debugging tool I find that eax,edx,abx are storing completely different values when decoy is used. What can I do to pull out the values I need to properly calculate them in my procedure?

.data
operand1   WORD    46
operand2   WORD    -20
dest       DWORD   0


.code

main PROC

    push   operand1                            ;14
    push   operand2                            ;12
    push   OFFSET dest                         ;8
    call   compute

 

exit
main ENDP





;-------------------------------------------------------------------------
;Compute
;-------------------------------------------------------------------------
compute PROC
    cmp dest, 0
    je L1
    cmp dest, 1
    je L2

L1:
    mov eax,[ebp + 12] 
    mov edx, [ebp + 14]    
    mov ebx, [ebp + 8] 

    call decoy
l2:
   ;ll encrypt


   ret 14
compute ENDP

;-------------------------------------------------------------------------
;Decoy
;-------------------------------------------------------------------------


decoy PROC
    push ebp
    mov ebp,esp   
    
    mov eax, 0

    ;mov ebx,[ebp + 12]                 
        
     ;mov edx, [ebp + 8]
     ;movsx edx, dx
     
     
     mov edx, [ebp + 8]
     mov ebx, [ebp + 12]

     ;add dx, [ebp + 10] 
    

    
    movsx eax, dx
    ;mov [ebx], eax



    call   WriteInt
   
   pop ebp
   
   ret 12
     
decoy ENDP
  • In your last question, you said you couldn't use global variables. But now you've added code in `compute` that does `cmp dest, 0`, accessing a global variable directly instead of using the pointer arg you passed on the stack. (Which is currently as `[esp+4]` at that point; you still haven't set up EBP as a frame pointer in `compute` (you only do that in `decoy`) so the EBP-relative accesses are loading some random garbage if they don't fault.) EBP isn't magic, it's just a register and you have to point it somewhere useful before `[ebp+8]` is meaningful. – Peter Cordes Mar 15 '22 at 18:07
  • the cmp dest stuff is temporary that I forgot to remove. should I have the ebp set up like ```;L1: push ebp mov ebp,esp mov eax,[ebp + 12] mov edx, [ebp + 14] mov ebx, [ebp + 8] pop ebp call decoy``` – Kevin T Chan Mar 15 '22 at 18:18
  • Yes, you should have. Except of course `mov eax, [ebp+12]` is a 4-byte load that gets both 16-bit args, because (like I mentioned on your last question), you packed them together instead of giving each arg a full 4-byte stack slot. Either way you'd want `movsx eax, word ptr [ebp+12]` to do a sign-extending 16-bit load. – Peter Cordes Mar 15 '22 at 18:25
  • Of course, if you `call decoy` instead of doing a `jmp decoy` tailcall, another return address will be on the stack between its return address and the original args, since you don't push fresh copies of the args after loading them in `compute`. – Peter Cordes Mar 15 '22 at 18:27
  • Also, `compute` does a `ret 14`, but `main` only did a total of 8 bytes of pushes (2 + 2 + 4), so it unbalances the stack. `pop ebp` and `ret` alone each pop 4 bytes, before the extra ESP+=14 happens. – Peter Cordes Mar 15 '22 at 18:28

0 Answers0