CSC231 No-no! and Be-Careful! situations

From dftwiki3
Jump to: navigation, search

--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