OSDev.org

The Place to Start for Operating System Developers
It is currently Mon Sep 16, 2019 10:34 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 14 posts ] 
Author Message
 Post subject: 2 questions acout hardware stack
PostPosted: Thu Feb 03, 2011 3:26 pm 
Offline
Member
Member

Joined: Thu Aug 12, 2010 7:25 am
Posts: 99
1. When i pass arguments on stack to a function, wich contain values i use as counters for loops, whats better, copy them, or modify directly on stack?
I ask this questions, because i dont want to break anything used for debugging, i know how painfull it is to have to copy stack of function before calling it because it modify it.



2. When allocation memory on stack, should i use enter instruction (wich is missing in 8086), rep stos (wich is avaiable on all cpus, and dword version is avaiable on all cpus supporting pmode), or sub sp,X (wich might defeat purpose of guard page if i use too big value).


Top
 Profile  
 
 Post subject: Re: 2 questions acout hardware stack
PostPosted: Thu Feb 03, 2011 4:51 pm 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 3:45 am
Posts: 9284
Location: On the balcony, watching the Swedish Chef
1: Arguments on the stack may normally be changed by the called procedure. local variables may not. Obviously, make backups where necessary.

2: rep stos* is only useful when you want to memset a local array. If you need to probe a stack to trigger guard pages, use page-size increments. Using push ebp; mov ebp, esp; sub esp, ...; is faster than using the microcoded ENTER instruction.

Also, guard pages and having a 8086 are mutually exclusive. Why do you need to consider both?

_________________
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]


Top
 Profile  
 
 Post subject: Re: 2 questions acout hardware stack
PostPosted: Thu Feb 03, 2011 4:55 pm 
Offline
Member
Member

Joined: Tue Jun 15, 2010 9:27 am
Posts: 255
Location: Flyover State, United States
This belongs in the General Programming forum, but I'll answer it here and then this will all get moved with it.

1. To pass arguments to a function, you push them on the stack in some predefined order and then the function you call knows which order they were pushed. As for local variables, they are allocated on the stack, but in a different manner (using a base pointer) such that it is possible to clean up the stack at the end of a function without knowing how much was allocated.

There are two main ways of cleaning the stack up when returning from a function, C calling convention and PASCAL calling convention. In both of these conventions, arguments are passed from right to left*. There are others as well.
A function declared with C convention looks like this:
Code:
; void some_function(int val)
some_function:
     push ebp
     mov ebp, esp      ; Create a stack frame
     sub esp, 4          ; Allocate a single int-sized local variable
     ; Do things with the variable here
     mov esp, ebp      ; Restore the old ESP
     pop ebp             ; Restore the old EBP
     ret


And it is called like this:
Code:
     push some_value
     call some_function
     add esp, 4          ; The caller is responsible for cleaning up pushed parameters


In PASCAL convention, however, the function cleans up the stack:
Code:
; int PASCAL some_other_function(int val)
some_other_function:
      push ebp
      mov ebp, esp     ; Uses the same kind of stack frame as C
      ; Do something
      mov esp, ebp
      pop ebp
      ret 4                 ; This adjusts ESP so the pushed argument is considered popped


And you call it like this:
Code:
     push some_other_value
     call some_other_function
     ; Stack is cleaned up for us, don't have to do anything.


2. I would use sub sp, xxx. rep stos has nothing to do with setting up a stack frame, and it doesn't even affect ESP. I think you can still use the bound instruction to make sure your stack isn't broken, even if you didn't use enter.

* PASCAL might have been originally the other way around but Microsoft changed it?

_________________
Getting_Started on the wiki
x86 technical information
Interrupt Jump Table
Real Programmers Don't Use Pascal
My open-source projects


Top
 Profile  
 
 Post subject: Re: 2 questions acout hardware stack
PostPosted: Thu Feb 03, 2011 6:38 pm 
Offline
Member
Member

Joined: Wed Oct 18, 2006 10:43 pm
Posts: 490
Location: Kansas City, KS, USA
Aaaand, moved to the General Programming sub-forum.


Top
 Profile  
 
 Post subject: Re: 2 questions acout hardware stack
PostPosted: Fri Feb 04, 2011 2:20 am 
Offline
Member
Member
User avatar

Joined: Mon Jan 26, 2009 2:48 am
Posts: 792
Tosi wrote:
* PASCAL might have been originally the other way around but Microsoft changed it?
In the C and STDCALL calling conventions, arguments are pushed from right to left. In the PASCAL calling convention they are pushed from left to right.

In the PASCAL and STDCALL calling conventions, the stack is restored by the called function. In the C calling convention it is restored by the calling function.

There are some differences between systems. Agner Fog maintains a very good document about it: http://www.agner.org/optimize/calling_conventions.pdf.


Top
 Profile  
 
 Post subject: Re: 2 questions acout hardware stack
PostPosted: Fri Feb 04, 2011 9:19 am 
Offline
Member
Member

Joined: Thu Aug 12, 2010 7:25 am
Posts: 99
Quote:
If you need to probe a stack to trigger guard pages, use page-size increments.

How do i know the page size? If i want to write code easly portable between paged and nonpaged mode, page size is 0. Page size might be also 4kb, 4mb, 2mb, 1gb.
I can of course assume 4096, but what if newest cpu would support smaller pages? Can intel/amd guarantee me that if i use max sub sp,4094 i wont skip entire page?


Top
 Profile  
 
 Post subject: Re: 2 questions acout hardware stack
PostPosted: Fri Feb 04, 2011 4:15 pm 
Offline
Member
Member

Joined: Tue Jun 15, 2010 9:27 am
Posts: 255
Location: Flyover State, United States
What I meant is that I've seen some functions in older Windows code that are declared PASCAL but the arguments are pushed in the order of STDCALL.

Quote:
How do i know the page size? If i want to write code easly portable between paged and nonpaged mode, page size is 0. Page size might be also 4kb, 4mb, 2mb, 1gb.
I can of course assume 4096, but what if newest cpu would support smaller pages? Can intel/amd guarantee me that if i use max sub sp,4094 i wont skip entire page?


Use CPUID or some similar functionality to figure out which paging extensions the CPU supports. If it doesn't support CPUID at all then it's probably good to stick with only 4kb pages.

_________________
Getting_Started on the wiki
x86 technical information
Interrupt Jump Table
Real Programmers Don't Use Pascal
My open-source projects


Top
 Profile  
 
 Post subject: Re: 2 questions acout hardware stack
PostPosted: Fri Feb 04, 2011 4:39 pm 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 3:45 am
Posts: 9284
Location: On the balcony, watching the Swedish Chef
a5498828 wrote:
Quote:
If you need to probe a stack to trigger guard pages, use page-size increments.

How do i know the page size? If i want to write code easly portable between paged and nonpaged mode, page size is 0. Page size might be also 4kb, 4mb, 2mb, 1gb.
I can of course assume 4096, but what if newest cpu would support smaller pages? Can intel/amd guarantee me that if i use max sub sp,4094 i wont skip entire page?

Is this an exercise in pendacy, because I think the is entire problem is moot - if you want portable code, use C. If you disagree and want portable code, do not allocate large structures on the stack. If you want fast code, use per-platform conditionals.

In your exceptional case, I recommend not using the stack :roll:

_________________
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]


Top
 Profile  
 
 Post subject: Re: 2 questions acout hardware stack
PostPosted: Fri Feb 04, 2011 9:00 pm 
Offline
Member
Member

Joined: Thu Aug 12, 2010 7:25 am
Posts: 99
Quote:
In your exceptional case, I recommend not using the stack

Ok, lets say i want to create extensive function, wich make use of many temporary values.
The only thing i can think of is using stack with push/pop instructions, storing temporary data on stack. For example, when making a loop store its counter on stack, load it only for tests/changes. What is i have multiple data, and want to access oldest? i have to pop everything, or address a stack.
For example, i can divide my function into sub functions each diffrent from the other by its own stack frame. When nesting another function i need to push bp and store current sp in bp in order to address stack in predictable manner. I could also place after bp previous bp, or even multiple bps to allow accessing higher stack frames. I belive its what enter instruction does. I only imagine how hard would be to manage the code then, must have keep track of every single item on stack, when removing position i would have to alter others, ehh... But i think its the only way to avoid 'push ax' multiple times.


Top
 Profile  
 
 Post subject: Re: 2 questions acout hardware stack
PostPosted: Sat Feb 05, 2011 9:25 am 
Offline
Member
Member

Joined: Tue Jun 15, 2010 9:27 am
Posts: 255
Location: Flyover State, United States
If you have a function which calls another function which calls another function and so on, you don't have to worry about cleaning up the stack when you are done in each function. The prologue, which sets up the stack frame, and the epilogue, which restores the old ESP value, do that for you. Also, local variables are only necessary if you run out of registers, which can happen easily in 32-bit assembly, or if you need some kind of array or structure that doesn't fit into a single 32-bit register. The stack frame makes it easy to access local variables once you have it set up.

Here is a skeleton for a function that uses a single local variable of DWORD size:
Code:
local_variable_function:
    push ebp
    mov ebp, esp           ; Set up stack frame
    sub esp, 4               ; Allocate 4 bytes for local memory
    ; Do something that uses all the registers here
    ...
    mov [ebp - 4], eax   ; Store the value in eax in the local variable
    ...
    mov eax, [ebp - 4]   ; Restore the local variable
    ...
    mov esp, ebp          ; This restores the old ESP since EBP isn't modified
    pop ebp
    ret


If you still don't understand about stack frames and local variables in assembly, I would recommend learning more while sticking to a higher-level language like C In the interim.

_________________
Getting_Started on the wiki
x86 technical information
Interrupt Jump Table
Real Programmers Don't Use Pascal
My open-source projects


Top
 Profile  
 
 Post subject: Re: 2 questions acout hardware stack
PostPosted: Tue Feb 08, 2011 8:00 am 
Offline
Member
Member
User avatar

Joined: Mon Jan 26, 2009 2:48 am
Posts: 792
Tosi wrote:
What I meant is that I've seen some functions in older Windows code that are declared PASCAL but the arguments are pushed in the order of STDCALL.
Functions for Win16 programs were declared PASCAL. In the Win32 headers, the PASCAL macro is defined as __stdcall so existing code needed less or no modification.


Top
 Profile  
 
 Post subject: Re: 2 questions acout hardware stack
PostPosted: Tue Feb 08, 2011 8:44 am 
Offline
Member
Member

Joined: Tue Jun 15, 2010 9:27 am
Posts: 255
Location: Flyover State, United States
Oh, I never programmed 16-bit windows so I didn't know that.
I can't help but feel some sense of respect for Intel and Microsoft for maintaining backwards compatibility for so long, even if it is only for outdated software.

_________________
Getting_Started on the wiki
x86 technical information
Interrupt Jump Table
Real Programmers Don't Use Pascal
My open-source projects


Top
 Profile  
 
 Post subject: Re: 2 questions acout hardware stack
PostPosted: Tue Feb 08, 2011 2:36 pm 
Offline
Member
Member
User avatar

Joined: Mon Jan 26, 2009 2:48 am
Posts: 792
Tosi wrote:
I can't help but feel some sense of respect for Intel and Microsoft for maintaining backwards compatibility for so long, even if it is only for outdated software.
Some forum members would say they don't feel any respect, for the very same reasons...


Top
 Profile  
 
 Post subject: Re: 2 questions acout hardware stack
PostPosted: Tue Feb 08, 2011 4:13 pm 
Offline
Member
Member

Joined: Tue Jun 15, 2010 9:27 am
Posts: 255
Location: Flyover State, United States
I don't want to be put into a position where I have to defend Microsoft, so I will retroactively make that last post sarcastic.
And I'm getting off topic.

_________________
Getting_Started on the wiki
x86 technical information
Interrupt Jump Table
Real Programmers Don't Use Pascal
My open-source projects


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group