12 December 2015, 16:41 | #1 |
Registered User
Join Date: Oct 2010
Location: France
Posts: 99
|
movem.l d0-d7/a0-a6,-(SP) inside a subroutine ?
Hi !
Could someone with a better knowledge than mine explain me why a "movem.l d0-d7/a0-a6,-(SP)" inside my SAVE_ALL subroutine will cause a guru, whereas it will work ok when outside the subroutine (put in between "bsr SAVE_ALL" and "bsr InitMusic"). BTW, don't pay any attention at my code pertinency (only for testing purposes !) Thank you ! Code:
move.l $4,a6 lea gfxname,a1 jsr -408(a6) move.l d0,a1 bsr SAVE_ALL bsr InitMusic bsr RESTORE_ALL rts InitMusic: move.w #%1000001000001111,$dff096 ; DMA Sound bsr mt_init VBL: move.l $dff004,d7 and.l #$1ff00,d7 cmp.l #303<<8,d7 bne.s VBL bsr mt_music btst #6,$bfe001 bne.s VBL bsr mt_end rts SAVE_ALL: move.l $26(a1),old_COP1 ; save old copperlist 1 move.l $32(a1),old_COP2 ; save old copperlist 2 jsr -414(a6) ; close lib move.w $DFF01c,old_IRQ ; Save IRQ enable flags move.w $DFF002,old_DMA ; Save DMACON register move.w #%0111111111111111,$DFF09a ; Disable IRQs move.w #%0111111111111111,$DFF096 ; Disable DMAs movem.l d0-d7/a0-a6,-(SP) rts RESTORE_ALL: move.l old_COP1,$DFF080 ; restore copperlist 1 move.l old_COP2,$DFF084 ; restore copperlist 2 move.w old_DMA,d0 ; restore dma control register ori.w #$8000,d0 ; Set high bit to enable 'set' move.w d0,$DFF096 ; Re-enable DMAs move.w old_IRQ,d0 ; Restore IRQ enabled register ori.w #$8000,d0 move.w d0,$DFF09a ; Re-enable IRQs movem.l (SP)+,d0-d7/a0-a6 rts gfxname: dc.b "graphics.library",0 even old_COP1: ds.l 1 old_COP2: ds.l 1 old_IRQ: ds.w 1 old_DMA: ds.w 1 Last edited by sodapop; 12 December 2015 at 16:47. |
12 December 2015, 16:57 | #2 | |
Registered User
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 55
Posts: 1,997
|
Quote:
|
|
12 December 2015, 17:19 | #3 |
Registered User
Join Date: Oct 2010
Location: France
Posts: 99
|
Wow ! totally beyond my comprehension...
|
12 December 2015, 17:46 | #4 |
Registered User
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 55
Posts: 1,997
|
|
12 December 2015, 19:48 | #5 |
Registered User
Join Date: Oct 2010
Location: France
Posts: 99
|
Thank you Don Adan, that makes sense now !
|
14 December 2015, 22:57 | #6 |
Registered User
Join Date: Oct 2010
Location: France
Posts: 99
|
Ok, I found out that a ADD.L #60,SP / SUB.L #60,SP before their respective RTS solved the problem (15 registers saved and restored x 4 bytes = 60)... stupid me !
|
15 December 2015, 10:19 | #7 |
Unregistered User
Join Date: Sep 2012
Location: Copenhagen / DK
Age: 43
Posts: 4,190
|
I'm no expert on 68k asm, but that sounds like kind of a hack.
|
15 December 2015, 10:21 | #8 |
ex. demoscener "Bigmama"
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,627
|
|
15 December 2015, 10:47 | #9 |
Registered User
Join Date: Oct 2010
Location: France
Posts: 99
|
I'm not a 68k expert by any means neither ! But for now, I can't see any reasons why this could go wrong... I only assumed the "return address" kept its place in the stack... and I'm quite an optimistic guy
|
15 December 2015, 10:54 | #10 |
Unregistered User
Join Date: Sep 2012
Location: Copenhagen / DK
Age: 43
Posts: 4,190
|
After doing the ADD.L instruction, your saved registers might get overwritten by some other instruction which puts stuff on the stack.
I think this kind of operation is better suited for a macro, thus you won't need to use BSR/RTS. This also allows the content to remain on the stack. Alternatively you can copy the return address 60 bytes ahead in the stack instead of doing ADD.L. Also a hack, but a bit safer. Edit: You'd probably want to remove the orphan address as well - but generally it is not good practice to do direct stack manipulation unless you really need to. |
15 December 2015, 11:13 | #11 |
Registered User
Join Date: Oct 2010
Location: France
Posts: 99
|
@demolition: yeah, you're probably right
|
15 December 2015, 18:42 | #12 |
Registered User
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
|
But, why would you want to do it like that?
I mean, the normal is to save regs at the beginning of a subroutine and restore them at exit Code:
superduperSubroutine: movem.l d0-d7/a0-a6,-(sp) bla-bla subroutine staff here bla-bla more bla-bla movem.l (sp)+,d0-d7/a0-a6 rts Code:
... ... movem.l d0-d7/a0-a6,-(sp) bsr anothersuperdupersubroutine movem.l (sp)+,d0-d7/a0-a6 ... ... Code:
;; save regs wherever you want movem.l d0-d7/a0-a6,saveregs ;; restore regs wherever you want movem.l saveregs,d0-d7/a0-a6 section foo,data ;; hold space for 15 registers saveregs: ds.l 15 |
15 December 2015, 21:28 | #13 |
Registered User
Join Date: Oct 2010
Location: France
Posts: 99
|
|
16 December 2015, 00:33 | #14 |
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
|
As long as you allocate, use, and deallocate, in the right order, it doesn't really matter.
One thing that could be good to know if you're playing with the stack like this: Exec uses your own stack when it switches tasks, so if you ever make multi-tasking programs then you can't use A7 as a general purpose register, it must always point to the top of your stack. In your example here it's not necessary to save any registers, neither for the CLI nor the Workbench, you only need to remember to pass a return value in D0 for CLI programs, typically 0. |
16 December 2015, 16:33 | #15 |
Registered User
Join Date: Oct 2010
Location: France
Posts: 99
|
@Leffmann: thank you for the enlightment. The purpose was only to put some "context saving" lines in a single subroutine (including "movem.l d0-d7..."). Need to put other things into it also, like the usual forbid to avoid multitasking, and so on...
|
18 December 2015, 18:45 | #16 | |
Glastonbridge Software
Join Date: Jan 2012
Location: Edinburgh/Scotland
Posts: 2,243
|
Quote:
|
|
18 December 2015, 18:58 | #17 |
Unregistered User
Join Date: Sep 2012
Location: Copenhagen / DK
Age: 43
Posts: 4,190
|
What I mean is that when you put stuff on the stack, make sure it is always pulled off again and in the intended order. Doing more advanced stack manipulation can be fine, but better think properly about it when it is implemented to make sure you don't get any unintended issues.
If you push the address of the error-handling routine (and maybe some parameters) on the stack it should never cause problems as long as the error handler cleans up whatever was put for it on the stack. |
18 December 2015, 19:14 | #18 |
Glastonbridge Software
Join Date: Jan 2012
Location: Edinburgh/Scotland
Posts: 2,243
|
yes indeed. a subroutine that puts stuff on the stack and leaves it there when it returns is a very strange and dangerous beast.
|
18 December 2015, 20:03 | #19 |
Registered User
Join Date: Jun 2008
Location: Boston USA
Posts: 466
|
The only valid use case is a C function which takes the address of a local to calculate how much of the stack is free. Ie returning the address of a local variable is insane otherwise
|
18 December 2015, 20:32 | #20 | |
Glastonbridge Software
Join Date: Jan 2012
Location: Edinburgh/Scotland
Posts: 2,243
|
yes, although we are not talking about returning the address of a local variable, but a function not leaving the stack in the same place it found it when it returns*, which means if the caller is doing relative (SP) addressing to access its own local variables, it will go completely out of whack and do nasty things.
Unless you have some specific, strict coding style that handles this sort of thing, i've thought before about what if you want a function to return an object whose size isn't known to the caller and might not be a constant... but i can't think of a neat way to do that anyway without using two stacks. (*which is impossible for a C function anyway) Quote:
Last edited by Mrs Beanbag; 18 December 2015 at 22:21. |
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Inside the Amiga | Washac | support.Hardware | 14 | 19 February 2010 17:52 |
movem in debugger | Ratte | support.WinUAE | 2 | 15 August 2009 23:10 |
Movem Pickout Amiga fun issue 06 | AliasXZ | support.Games | 0 | 12 August 2009 00:32 |
Something like Movem | MarlboroMan | Looking for a game name ? | 2 | 10 October 2004 12:47 |
Movem & 3D Motorrad (Amiga Mania) | andreas | request.Old Rare Games | 6 | 26 September 2004 01:29 |
|
|