English Amiga Board


Go Back   English Amiga Board > Coders > Coders. General > Coders. Tutorials

 
 
Thread Tools
Old 28 November 2010, 23:17   #1
jman
Registered User
 
Join Date: Nov 2010
Location: .
Posts: 351
REQ:ASM How to use buffers

Hello everyone,

pre-Commodore bankrupt Amiga user writing here (IRL developer on modern stuff), having fun with MC68000 assembly in his free time.

I'm dutifully following the good Amiga Machine Language ebook, two lines per day because I like to fully understand everything - so I test a lot of personal variations of what I read. This is to say that I don't mind spending hours staring at the Devpac debugger moving stuff to/from registers.

So, back in topic, I'm trying to understand how to use a buffer and how can I move the "visible window" on A(n) from the debugger.
Everytime I issue a "(a0)+" instruction the pointer to the register shifts forward and I don't see anymore the value inserted unless I "go back" with a SUBQ. I usually use ADDQ and SUBQ to visually move the register cursor and check the values - this looks kind of lame, I guess.
However there's something puzzling me, please have a look at the following code snippet:

1: run:
2: lea buffer,a0 ; removing this instruction or ...
3: move.w #2,(a0) ; changing this to (a0)+ or ...
4: subq.l #1,a0
5: move.w #3,(a0) ; removing this instruction: solves.
6: rts
7:
8: buffer:
9: dcb.w 9,0
10:
11: end

Questions:
1) What is the real purpose of defining a 'buffer' in this code? I can access to A0 register either way.
2) If I run this code into the debugger, at line 6 in the disassembly window the RTS changes into a DC.W $4E00 and eventually falls into an illegal exception. As commented on line 2,3 and 5 slightly changing the code makes the RTS to stay there and be executed.

Can you give me an insight on how to explain this behaviour?

Thanks a lot.

Antonio
jman is offline  
Old 29 November 2010, 00:46   #2
Codetapper
2 contact me: email only!
 
Codetapper's Avatar
 
Join Date: May 2001
Location: Auckland / New Zealand
Posts: 3,182
a0 is just an address register, no actual block of memory is allocated. They just contain pointers to addresses (effectively numbers). The block of memory called buffer means that chuck of memory is set aside and can be referenced at any point in your code (which might be huge) by referencing the name buffer.

The rts instruction is $4e75 in hexadecimal. When you do your subq.l, you are moving the address register a0 back one byte so it's pointing to the $75 chuck of memory. Then you move the word #3 into it (illegal on 68000, but I guess devpac allows it as a 68020+ instruction or something) meaning you would now have $4e $00 $03 as 3 consecutive memory locations. Now a0 points to $4e00!
Codetapper is offline  
Old 29 November 2010, 08:48   #3
pmc
gone
 
pmc's Avatar
 
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
Hello jman

The problem with the code is this:

Quote:
Originally Posted by jman
4: subq.l #1,a0
you shouldn't set address registers to point at odd memory addresses.

I know what you mean about checking values in a debugger though. When you use:

Code:
move.w #value,(a0)+
you can't see what's just been placed in the address a0 points at as the debugger has already incremented the a0 register to point at the next word in memory.

But, if you want to see what got placed in a0 before the post increment was done and you have a spare data register available (in this case, I'll use d7 as the example spare register) then you could do this line of code after your move.w to (a0)+:

Code:
 
move.w -2(a0),d7
And d7 would then show the contents of one word less in memory than what a0 currently points to. In other words you still get to see what went into a0 without having to subtract from a0 at all so the a0 register still points at the correct memory address as per the (a0)+ earlier.

Hope that helps.
pmc is offline  
Old 29 November 2010, 09:35   #4
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
Quote:
Originally Posted by Codetapper View Post
Then you move the word #3 into it (illegal on 68000, but I guess devpac allows it as a 68020+ instruction or something)
Any assembler will allow that instruction as the instruction itself is perfectly valid, move.w #xx,(ax) is allowed on 68000 after all. Thus there won't be any error message when assembling the code but it'll of course only work on 68020+.

Quote:
Originally Posted by pmc View Post
you shouldn't set address registers to point at odd memory addresses.
This is not exactly correct, there is no problem doing that as long as you only perform byte accesses. move.b #1,(a0) f.e. is perfectly fine on 68000 when a0 points to an odd address.

Quote:
Originally Posted by jman
1) What is the real purpose of defining a 'buffer' in this code? I can access to A0 register either way.
In your example the buffer is needed to store more than one value. You have allocated 9 words so you could store max. 9 values in that buffer.

F.e. you could have code like this:

lea buf,a0
move.w #1,(a0)+ ; a0 points to buf+2 after that instruction
move.w #2,(a0)+ ; a0 points to buf+4 after that instruction

If you only need to store one value, this would be totally fine and all you need:
buf dc.w 0 ; allocate 1 word

Hope that helps, if not feel free to ask.

Last edited by StingRay; 29 November 2010 at 09:41. Reason: additions
StingRay is offline  
Old 29 November 2010, 10:26   #5
pmc
gone
 
pmc's Avatar
 
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
Quote:
Originally Posted by StingRay
This is not exactly correct, there is no problem doing that as long as you only perform byte accesses. move.b #1,(a0) f.e. is perfectly fine on 68000 when a0 points to an odd address.
You are (of course... ) correct my friend. Funny thing is, I remember doing just that (byte access to odd address) myself in a sprite movement routine I did so why I wrote that I don't know...

I'll blame it on this very cold early morning.
pmc is offline  
Old 30 November 2010, 23:13   #6
jman
Registered User
 
Join Date: Nov 2010
Location: .
Posts: 351
@everyone: thanks for your kind and prompt contribution.

I took some time to experiment and think over your suggestions. Some things you mentioned are clear, others confused me more (I'm a total beginner, that was clear in the first place), so here are some further questions that arised:

Quote:
Originally Posted by Codetapper View Post
The rts instruction is $4e75 in hexadecimal. When you do your subq.l, you are moving the address register a0 back one byte so it's pointing to the $75 chuck of memory. Then you move the word #3 into it (...) meaning you would now have $4e $00 $03 as 3 consecutive memory locations. Now a0 points to $4e00!
This really blew my head off: what do you mean by rts is $4e75? Every instruction has an address in memory??
EDIT: I've found this: http://www.sarnau.info/atarirotection_speedball. Looks interesting. Still I don't understand what are those hex values next to each ASM instructions.

Quote:
Originally Posted by StingRay View Post
You have allocated 9 words so you could store max. 9 values in that buffer.
Question: having allocated a n sized buffer, what happens if I try to allocate/call a nth+1 element? Example:

Code:
run:
    lea        buf,a0
    move.w    #8,(a0)+
    move.w    #6,(a0)+
    move.w    #4,(a0)+
    move.w    #2,(a0)+
    lea        buf,a1
    rts
buf: dc.w 1,2
In A1 I see 8,6,4,2 and nothing seems to be 'lost', no error whatsoever. Why? I expected that "4" and "2" would be gone while loading buf in a1.

Again, thanks for your kind help.

Antonio

Last edited by jman; 30 November 2010 at 23:44. Reason: added link
jman is offline  
Old 01 December 2010, 00:54   #7
Codetapper
2 contact me: email only!
 
Codetapper's Avatar
 
Join Date: May 2001
Location: Auckland / New Zealand
Posts: 3,182
Quote:
Originally Posted by jman View Post
This really blew my head off: what do you mean by rts is $4e75? Every instruction has an address in memory??
EDIT: I've found this: http://www.sarnau.info/atarirotection_speedball. Looks interesting. Still I don't understand what are those hex values next to each ASM instructions.
Computers don't know assembler, the instructions are converted from assembly language to hexadecimal opcodes by an assembler such as Asm-One, Barfly or Devpac.

Any cracker worth their salt knows common ones off the top of their head like:

$4e71 = nop
$4e75 = rts
$7000 = moveq #0,d0
$7200 = moveq #0,d1
$60xx = bra * + (xx + 2) = eg. $6002 will skip ahead 4 bytes from the instruction.

Quote:
Question: having allocated a n sized buffer, what happens if I try to allocate/call a nth+1 element?

In A1 I see 8,6,4,2 and nothing seems to be 'lost', no error whatsoever. Why? I expected that "4" and "2" would be gone while loading buf in a1.
It will just start overwriting memory. On the Amiga where memory is not protected, it will eventually destroy something, but in this case there is probably a pretty big safety buffer where the code resides so it's probably not destroying anything vital if you do this.

However, code like this:

Code:
        lea $400,a0
_1      move.l #0,(a0)+
        bra _1
Will definitely crash your Amiga as it clears all memory!
Codetapper is offline  
Old 01 December 2010, 01:41   #8
jman
Registered User
 
Join Date: Nov 2010
Location: .
Posts: 351
Quote:
Originally Posted by Codetapper View Post
Computers don't know assembler, the instructions are converted from assembly language to hexadecimal opcodes by an assembler such as Asm-One, Barfly or Devpac.
... and since a CPU only has a 0/1 "language" $4e75 becomes a "100111001110011" operation code sent to the CPU along with the rest of the instruction.
Definitively interesting. With such insights, concepts like memory protection, opcodes and so on now are much more clear. Thanks, really.

g'night.
jman is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
[REQ:ASM] Reading a keystroke jman Coders. Tutorials 34 17 August 2023 12:36
[REQ:ASM] Sprite collisions basics jman Coders. Tutorials 5 03 September 2011 00:07
[REQ:ASM] Loading a static image and its palette jman Coders. Tutorials 3 04 June 2011 14:08
[REQ:ASM] Assembling and running jman Coders. Tutorials 9 07 May 2011 18:39
REQ:ASM getting elapsed time on A1200 jman Coders. Tutorials 18 11 January 2011 22:24

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 13:14.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.07523 seconds with 13 queries