CSC231 No-no! and Be-Careful! situations
--D. Thiebaut 13:15, 10 November 2010 (UTC)
What's wrong with the following code?
; this function will compute N results and store them in the stack...
compute:
pushad
mov ecx, N ;loop some number of times
mov eax, data1 ;get some data
mov ebx, data2
.for: call doSomething ;operate on eax and ebx
; on return, eax contains
; result we're interested in
push eax ;save result in stack
loop .for
;;; we're done
popad
ret
Code to be Avoided...
Why should we avoid coding functions as shown below?
compute:
pushad
push ebp
mov ebp, esp
;;; get parameters from the stack
mov ecx,[ebp+XX] ;XX is some offset
mov eax,[ebp+YY] ;YY is some offset
mov ebx,[ebp+ZZ] ;ZZ is some offset
.for: call doSomething ;operate on eax and ebx
; on return, eax contains
; result we're interested in
loop .for
;;; we're done
pop ebp
popad
ret 3*4
Helpful Trick
- We can use the %define directive to assign names to our parameters living in the stack.
- More information on %define: Nasm Preprocessor
- Example:
;;; sumproc3.asm ;;; D. Thiebaut CSC231 ;;; third of a series of programs illustrating how to pass and receive ;;; information to and from a function in assembly. ;;; ;;; This and all associated programs simply add the contents of ;;; two variables a and b and store the resulting sum in a variable ;;; called result (all are double words) ;;; ;;; this version passes a and b by value through the stack. the ;;; sum is passed back in the stack. SYS_EXIT equ 1 SYS_WRITE equ 4 STDOUT equ 1 ;; ------------------------- ;; data segment ;; ------------------------- section .data a dd 0x1234 ; operand 1 b dd 0x5555 ; operand 2 result dd 0 ; where sum will end up ;; ------------------------- ;; code area ;; ------------------------- section .text global _start _start: push eax ; make room in the stack for result push dword [a] ; pass copy of a push dword [b] ; pass copy of b call sum pop dword [result] ; get sum from stack and restore stack ;; exit() mov eax,SYS_EXIT mov ebx,0 int 0x80 ; final system call ;;; ------------------------------------------------------- ;;; sum function ;;; gets 2 dwords from stack and puts sum in stack for main ;;; program to receive. ;;; registers modified: eax ;;; ;;; stack looks like this after first 2 instructions: ;;; ;;; +----------+ ;;; | "empty" | <-- ebp+16 ;;; +----------+ ;;; |copy of a | <-- ebp+12 ;;; +----------+ ;;; |copy of b | <-- ebp+8 ;;; +----------+ ;;; |retrn addr| <-- ebp+4 (plus 4 because double words!) ;;; +----------+ ;;; |"old" ebp | <-- ebp <-- esp ;;; +----------+ ;;; | | ;;; ------------------------------------------------------- sum: push ebp mov ebp,esp %define sum_a dword[ebp+12] %define sum_b dword[ebp+8] %define sum_res dword[ebp+16] mov eax,sum_b ; get copy of b add eax,sum_a ; get copy of a mov sum_res,eax ; put sum in reserved space in stack pop ebp ret 8 ; we get rid of 2 dwords in stack and ; keep one for main program to get sum