BBC BASIC
« Why not POP? »

Welcome Guest. Please Login or Register.
Feb 20th, 2017, 12:39am


Cross-platform BBC BASIC (Win32, Linux x86, Android, Mac OS-X, Raspberry Pi)

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Why not POP?  (Read 37 times)
hellomike
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 30
xx Why not POP?
« Thread started on: Feb 3rd, 2017, 10:34am »

Hi,

Because I need to have a new collating sequence for use in SQLite, I can't postpone learning more about IA-32 assembler anymore.

The BB4W help pages and the excellent articles in the Wiki assist a great deal, nevertheless I made BB4W crash a lot the last couple of days :)

Here is one thing I fail to understand. Its about the last assembler code at the bottom of this page
http://bb4w.wikispaces.com/Passing+data+to+assembler+code

It reads:
Code:
      .address
      mov ebp,esp
      mov eax,[ebp+4] ; now eax=par1%
      mov ebx,[ebp+8] ; now ebx=par2%
      mov ecx,[ebp+12] ; now ecx=par3%
      mov edx,[ebp+16] ; now edx=par4%
      ; do something useful
      ret 16 ; discard parameters 

Getting the values while they are still on the stack and at the end clear the stack using 'ret 20' seems devious to my novice mind.

I would think that the following is much more logical
Code:
      .address
      pop eax
      pop ebx
      pop ecx
      pop edx
      ; do something useful
      ret 

However, you guessed it, it makes BB4W crash.

Hope anyone can clarify the need to use the documented approach.
Thanks a lot.

Mike
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 358
xx Re: Why not POP?
« Reply #1 on: Feb 3rd, 2017, 1:54pm »

on Feb 3rd, 2017, 10:34am, hellomike wrote:
However, you guessed it, it makes BB4W crash.

You're forgetting that the stack also holds the return address, i.e. the address to which the CPU must jump to return to the calling code. Once you factor that in, the difference between the working code and the code that crashes becomes obvious.

Here are the stack contents on entry to the subroutine:

Code:
[esp+16]: 4th parameter
[esp+12]: 3rd parameter
[esp+8]: 2nd parameter
[esp+4]: 1st parameter
[esp+0]: return address 

What your code does is to pop the return address into eax (which you most definitely don't want to do) and then eventually the subroutine 'returns' to an address which corresponds to the value of the 4th parameter. Bang!!!

If the ret instruction is to work correctly the value of the stack pointer when the instruction is executed must be the same as it was when the subroutine was entered, but your code guarantees that it won't be!

Anyway, the code I listed is the standard way in which a subroutine should get its parameters off the stack, and if you disassemble code generated by (say) a C compiler you will see this technique being used all the time.

You may think your alternative is "more logical" but you'd be hard-pressed to find any experienced assembly language programmer who agrees with you!

Richard.
User IP Logged

hellomike
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 30
xx Re: Why not POP?
« Reply #2 on: Feb 4th, 2017, 09:29am »

LOL! Of course it was something as fundamental as this. Maybe unwittingly somehow I'm still used to think about a R14 link register smiley
Your explanation makes perfect sense.

Quote:
....and if you disassemble code generated by (say) a C compiler you will see this technique being used all the time.

Getting this kind of info is also is very welcome.

Well, with this new insight, my collating routine now returns correctly back to SQLite, after using the "CompareString" API.

Thanks Richard.

Mike
User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

Donate $6.99 for 50,000 Ad-Free Pageviews!


This forum powered for FREE by Conforums ©
Sign up for your own Free Message Board today!
Terms of Service | Privacy Policy | Conforums Support | Parental Controls