Reputation: 55
I have a question: if General Purpose Registers(GPRs) are shared between stacks (I think they are), would it be true that the only way to pass the address of stack space is to use GPRs?
Any advice would be very appreciated. Thanks in advance.
segment .data
prompt db "Enter an integer number (0 to quit): ",0
segment .text
main:
enter 0,0
pusha
mov eax, prompt
call print_string
call print_nl
call read_int
mov dword [ebp+8], eax
dump_stack 1,2,4
call calc_sum
mov eax, [ebp+12]
call print_int
call print_nl
popa
mov eax, 0 ; return value
leave ; deallocate stack frame
ret
; sump [ebp+12] > int ptr
; n [ebp+8] > current number
; return address [ebp+4]
; ebp [ebp]
; sum [ebp-4]
; i [ebp-8]
global calc_sum
calc_sum:
enter 4,0 ; stack space allocated for sum
push ebx ; very important!
mov dword [ebp-4], 0 ; sum = 0
dump_stack 1,2,4 ; print the content of stack from ebp-8 to ebp+16
mov ecx, 1 ; ecx psuedo code i
for_loop:
cmp ecx, [ebp+8] ;cmp i and n
jnle end_for ; if i<= n else , exit
add [ebp-4], ecx ; sum+=i
inc ecx
jmp short for_loop
end_for:
mov ebx, [ebp+12] ;ebx = sump
mov eax, [ebp-4] ;eax = sum
mov [ebx], eax
pop ebx ;restore ebx
leave
Enter an integer number (0 to quit):
10
Stack Dump # 1
EBP = BF86F3D8 ESP = BF86F3B8
+16 BF86F3E8 BF86F47C
+12 BF86F3E4 BF86F474
+8 BF86F3E0 0000000A
+4 BF86F3DC B76134E3
+0 BF86F3D8 00000000
-4 BF86F3D4 00000001
-8 BF86F3D0 BF86F474
Stack Dump # 1
EBP = BF86F3B0 ESP = BF86F3A8
+16 BF86F3C0 BF86F3D8
+12 BF86F3BC 00000000
+8 BF86F3B8 00000000
+4 BF86F3B4 080484AC
+0 BF86F3B0 BF86F3D8
-4 BF86F3AC 00000000
-8 BF86F3A8 B77A0FF4
Segmentation fault (core dumped)
dump_stack 1,2,4 (-8~+16)
shows a stack frame. I attached the result of the execution program. I got this result just in case you don't understand dump_stack
.
BTW: I use NASM
and gcc
as tools for learning purposes.
Upvotes: 1
Views: 998
Reputation: 4369
First of all, there is only one stack, so You cannot share anything between stacks as there is only one (actually it is a simplification, but you can think about it this way as long as you are beginner).
Think of stack like of some space for your data. Every push
call
or ret
just reads/writes to this place. Registers like eax
are not affected (until you call pop eax
:) ).
So every write to stack with push
or call
decreases esp
register (this is why we say it grows down), and every read with pop
or ret
increases it. esp
always points to the top of the stack. You can read or modify esp
by mov
ing it to/from another register but you must know what you are doing.
Upvotes: 3