Assembly Language for Beginners

(nextflipdebug2) #1

1.7. STACK


; Line 4
pop ebp
ret 0
?f@@YAXXZ ENDP ; f


...Also if we turn on the compiler optimization (/Oxoption) the optimized code will not overflow the stack
and will workcorrectly^58 instead:


?f@@YAXXZ PROC ; f
; File c:\tmp6\ss.cpp
; Line 2
$LL3@f:
; Line 3
jmp SHORT $LL3@f
?f@@YAXXZ ENDP ; f


GCC 4.4.1 generates similar code in both cases without, however, issuing any warning about the problem.


ARM


ARM programs also use the stack for saving return addresses, but differently. As mentioned in “Hello,
world!” (1.5.4 on page 19), theRAis saved to theLR(link register). If one needs, however, to call another
function and use theLRregister one more time, its value has to be saved. Usually it is saved in the
function prologue.


Often, we see instructions likePUSH R4-R7,LRalong with this instruction in epiloguePOP R4-R7,PC—thus
register values to be used in the function are saved in the stack, includingLR.


Nevertheless, if a function never calls any other function, inRISCterminology it is called aleaf function^59.
As a consequence, leaf functions do not save theLRregister (because they don’t modify it). If such
function is small and uses a small number of registers, it may not use the stack at all. Thus, it is possible
to call leaf functions without using the stack, which can be faster than on older x86 machines because
external RAM is not used for the stack^60. This can be also useful for situations when memory for the stack
is not yet allocated or not available.


Some examples of leaf functions:1.10.3 on page 103,1.10.3 on page 103,1.278 on page 315,1.294 on
page 333,1.22.5 on page 333,1.186 on page 210,1.184 on page 208,1.203 on page 226.


Passing function arguments


The most popular way to pass parameters in x86 is called “cdecl”:


push arg3
push arg2
push arg1
call f
add esp, 12 ; 4*3=12


Calleefunctions get their arguments via the stack pointer.


Therefore, this is how the argument values are located in the stack before the execution of thef()func-
tion’s very first instruction:


ESP return address
ESP+4 argument#1, marked inIDAasarg_0
ESP+8 argument#2, marked inIDAasarg_4
ESP+0xC argument#3, marked inIDAasarg_8
... ...

(^58) irony here
(^59) infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka13785.html
(^60) Some time ago, on PDP-11 and VAX, the CALL instruction (calling other functions) was expensive; up to 50% of execution time
might be spent on it, so it was considered that having a big number of small functions is ananti-pattern[Eric S. Raymond,The Art
of UNIX Programming, (2003)Chapter 4, Part II].

Free download pdf