PROBLEM With Stack Pointer (Assembly)

Discussion in 'Programmer's Corner' started by frogacult, May 2, 2008.

  1. frogacult

    Thread Starter Member

    Apr 30, 2008
    27
    0
    hello, i need some help with a program in assembly :

    i have the sum of D0,D1 and pushed it at SP and i want to recall the most significant word of this sum from SP in the register D4.
    how i do this ?:confused:

    i work with 68000 motorola microcotroller
     
  2. Mark44

    Well-Known Member

    Nov 26, 2007
    626
    1
    What instruction did you use to push the sum? Was it PEA? I'm looking in the reference I have for the 68000 instruction set and I don't see PUSH or POP instructions, which is what I would use on x86 machines.

    Anyway, assuming you can get back what you pushed, and it's in D4, you can use SWAP to swap the high and low words, then use ANDI.L #$0FFFF, D4 to zero out the high word, and there you have it.

    Can I ask why you pushed the sum onto the stack?
    Mark
     
  3. frogacult

    Thread Starter Member

    Apr 30, 2008
    27
    0
    finally i solved it.
    if u wanna move something to SP you write this >> MOVE.L D1,-(SP)
    If u wanna recall something from SP you write this >> MOVE.L (SP)+,D2
    Now my problem was that the sum assigned into register D1 was Longword and the excercise was asking to recall the most signifficant word of D1 from SP and i wrote this >> MOVE.W (SP)+,D1 << and it worked :D
    it was very easy finally. I had to push the sum onto the stuck because the excercise asked it.
    Im gonna ask you a lot of things in the future dude.
    Thanx again for your interest


    Mike
     
  4. Mark44

    Well-Known Member

    Nov 26, 2007
    626
    1
    Mike,
    I saw some M68000 emulator software called EASy68K that I'm going to download so I can actually try out things first:)

    Do you understand what's going on with the push operation? I.e., with this...
    Code ( (Unknown Language)):
    1.  
    2. MOVE.L D1,-(SP)
    3.  
    There are a couple of things that are happening, in this order:
    1. Stack pointer (SP) is decremented by 4 (since you're moving a longword, which is 4 bytes).
    2. The
    value in D1 is copied to this new location on the stack.

    After the move, SP points to the value you moved.

    A pop operation is essentially doing the opposite.
    Code ( (Unknown Language)):
    1.  
    2. MOVE.L (SP)+,D2
    3.  
    1. The longword value that SP is pointing to is copied to D2.
    2. SP
    is incremented by 4, since you're moving a longword.

    You might notice that I did a MOVE.L, which was different from what you did. Assuming there have been no other pushes or pops, SP contains the same address as it did before the push operation.

    I'll have to think about why your MOVE.W (SP)+, D2 gave you the low word that you wanted. I'm pretty sure it has something to do with the way bytes are ordered in a word or longword in the Motorola architecture, which is the opposite of the way they are in the Intel (or AMD) x86 architecture.

    The terms for this are "little-endian" and "big-endian."

    Anyway, it looks like you learned a lot of good stuff in your assembly exercise. Congrats!

    Mark
     
  5. frogacult

    Thread Starter Member

    Apr 30, 2008
    27
    0
    That's true Mark, and i'm happy because at the begin, all this stuff was very strange for me and now i like it ;)


    I tried out another way to take the most signifficant word from SP and it worked but i dont know if it is tha right way but the result is that i want.

    i wrote this code :

    MOVE.L (SP)+, D1
    SWAP D1 // The 8 MSB goes to 8 LSB, and 8 LSB goes to 8 MSB
    EXT.W D1 // something like converts an extension in word

    try it out ;)

    Mike
     
  6. Mark44

    Well-Known Member

    Nov 26, 2007
    626
    1
    Mike,
    I'm now using the EASy68K emulation software I mentioned earlier, and it's pretty cool. I think I've found a bug in it, though, since it won't handle this without giving an error:
    Code ( (Unknown Language)):
    1.  
    2. MOVE.W  -(A0), (A1)+
    3.  
    As soon as I'm registered on their forum site, I'll submit this bug.

    Anyway, I took a look at what you came up with to push a value on the stack and pop one off.
    Code ( (Unknown Language)):
    1.  
    2.         CLR.L D2
    3.         MOVE.L #$12345,D1
    4.         MOVE.L D1,-(SP)  ; push value in D1 on stack
    5.         MOVE.W (SP)+,D2  ; pop MSW word at SP to D2
    6.  
    The push operation (2nd MOVE, above) decrements the stack pointer by 4 bytes, the size of a dword (the 68000 folks seem to call this a longword), and then move the value of D1 (#$12345) into the location pointed to by SP.

    In my program, before the push operation, SP was $1000000. After the push operation, SP had been reset to $FFFFFC, an address 4 bytes lower in memory. As the stack grows (stuff gets pushed onto it), the top of the stack moves lower in memory.

    The pop operation as you did it moves the value pointed to by SP to D2. A key question here is: "we know which byte in memory we're looking at, but how big is the thing we're looking at?" It all hinges on the operation you're using, whether it's a byte operation, word operation, or dword operation. In your code, with MOVE.W, we're looking at the two byte, or word quantity starting at the location SP points to.

    As mentioned before, SP is $FFFFFC. The four bytes in memory starting at this location are:
    00 01 23 45

    With the MOVE.W instruction, you get the bytes at $FFFFFC and $FFFFFD, or 00 01, which in hex is 0x0001, or in the 68000 notation, #$0001.

    Finally (this has been a bit long-winded), because the MOVE.W instruction popped two bytes off, SP gets reset to $FFFFFE, which is different from what it started out as, and the lower word is still on the stack. If you wanted it, you could do another MOVE.W to get it, and also get the stack back to its original state.

    Mark
     
Loading...