21 March 2024, 13:58 | #1 |
Registered User
Join Date: May 2022
Location: Canada
Posts: 140
|
Double the memory address
Hello ASM coders,
I am trying to optimize this and I am stuck. Suppose you have a buffer in memory. I would like to compute its address times two + 24, like so: Code:
move.l #buffer+24, a1 add.l #buffer, a1 Code:
move.l #buffer+buffer+24, a1 Could you help me find a way or if it is even possible? Reason: The purpose of this "buffer times two" is to have an efficient buffer swap. Imagine in pseudo code: Code:
<init> byte buffer[48]; // enough space for two buffers of 24 bytes byte* current_buffer = &buffer[0]; <usage> current_buffer = &buffer[0] + &buffer[24] - current_buffer; The code with the 'add.l' line works, but it bugs me to have to runtime-add at link-time constant. |
21 March 2024, 14:13 | #2 |
Registered User
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 56
Posts: 2,047
|
I dont use vasm. Maybe try?
lea 2*buffer+24,A1 |
21 March 2024, 14:14 | #3 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,491
|
lea 24(a1,a1.l),a1 |
21 March 2024, 14:25 | #4 |
Registered User
Join Date: May 2022
Location: Canada
Posts: 140
|
Thank you both!
Don: similar to the move buffer+buffer: illegal relocation > lea 2*buffer+24,A1 ross: nice and compact, but it is still added at runtime instead of compile time. (however, it is efficient and clever!) |
21 March 2024, 14:29 | #5 | |
Registered User
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,437
|
Quote:
I'd personally use ross's method. Safe, simple and doesn't care about which address buffer is located at. |
|
21 March 2024, 15:01 | #6 |
Registered User
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 56
Posts: 2,047
|
If You want to use similar code, You can try:
Code:
lea buffer+24/2,A1 add.l A1,A1 |
21 March 2024, 15:11 | #7 |
ex. demoscener "Bigmama"
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,643
|
|
21 March 2024, 16:55 | #8 |
Registered User
Join Date: Jun 2016
Location: europe
Posts: 1,066
|
You can't multiply, shift, swap or split in some way, divide, and/or/eor/not/neg a relocatable address, you can only add or subtract a constant.
A very simple example... If your code looks like abc+$20, when you hexdump it you will see e.g. $00000320, and then in run-time when your program is loaded at e.g. address $120000, the loader will add that and then address will finally become $120320. Because $120000 is the unknown at compile time. So what in c/c++ looks like a simple solution, when you translate it to asm it won't necessarily end up being pretty. I feel little in the dark here, not seeing the whole picture... If you have to do the swap multiple times, maybe load both pointers to aregs and use exg ax,ay? Or use eor to swap, something like: Code:
; a4=&buffer[0], d4=curr_offset eor.w #24,d4 ; swap lea (a4,d4.w),a0 ; proceed to use a0 Code:
; e.g. if a5 is a base register pointing to my_data, otherwise use absolute addressing or pc-relative where possible eor.w #24,offset-my_data(a5) ; swap ... lea buffer,a0 add.w offset-my_data(a5),a0 ; proceed to use a0 |
21 March 2024, 17:53 | #9 |
Registered User
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 56
Posts: 2,047
|
Right, anyway Amiga exe file can handle similar code:
Code:
move.l #buffer+buffer+24, a1 2 relocs are necessary. Not only 1. Then this is only question of assembler, if can create 2 relocs for this code. For single reloc this is impossible, for two relocs this is possible. Anyway it looks like code can be optimized for size and speed, if 2 relocs will be used Then remz idea is not bad, like look after first look. And he can manually add 1 reloc to Amiga exe file relocs table, if no assembler has support for this code. |
21 March 2024, 17:54 | #10 |
Registered User
Join Date: May 2022
Location: Canada
Posts: 140
|
Thank you for your suggestions and replies. It makes a lot of sense.
My request is slightly silly, it is a bit like if I was asking the loader to "store the address of this symbol but doubled". It would be unlikely this feature would exist. (But technically, it is the same job as relocating/updating the addresses on loading.) I incorrectly thought it was the linker's job, but in fact this is done by the loader when placing the executable in memory and "burning-in" all the addresses. I'll stick with the solution of computing the double-address once at initialization and then using that at runtime. |
21 March 2024, 20:19 | #11 |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,316
|
Out of curiousity, why is there a need to double an an address? This is in almost all cases an indication of an improper design. There is BCPL and its BPTRs which require quadrupling pointers (and yes, it is quite a bizarre design), and I have seen something similar in the console device because its "attribute map" is word-sized, unlike the character map, and there it is also an indication of an improper design (the attribute map should not be reachable in such a way, but be really represented by a proper data structure - and no, the array is not the only useful data structure).
|
21 March 2024, 21:51 | #12 |
Registered User
Join Date: May 2023
Location: Norwich
Posts: 434
|
You don't need to double the address anywhere, that's not what your pseudo code is even doing.
The first buffer is &buffer, the second is &buffer+24 (assuming bytes but it's a fixed offset regardless) - all the maths works without ever having to double anything. I think you've confused yourself by thinking having the two "buffers" combined into one somehow means the second one is at double the address, but that's not what is happening. |
22 March 2024, 00:02 | #13 |
Registered User
Join Date: Jun 2016
Location: europe
Posts: 1,066
|
X is either A or B. A+B-X will give you B if X=A, or A if X=B (effectively a swap).
Code is logically OK, it's just not resolvable in compile time due to illegal arithmetics with relocatables, but as I already said there's no need for said arithmetics (with or without creative solutions like the one Don Adan proposed). Shorter and faster code is possible, but more details about usage are needed. And then there's also this: Amiga is only using a half of the 32-bit address space and "fortunately" it's safe to add arbitrary pointers, otherwise (e.g modern OS's) it could result in overflow and a bad pointer. So I'd simply call it a bad practice (but I'd still do it myself if it would save me a few cycles :P). |
22 March 2024, 01:36 | #14 |
Registered User
Join Date: May 2022
Location: Canada
Posts: 140
|
a/b: I don't think overflow would be an issue. Dealing with unsigned (modulo) arithmetic, it nevers overflows in fact. And the subtraction works anyway.
x=a x=a+b - x Will work even if a+b wraps around the 32-bit long. |
22 March 2024, 03:29 | #15 |
Registered User
Join Date: Jun 2016
Location: europe
Posts: 1,066
|
Uff, you're right. Should've finished the calculation, trapv ftl ><.
|
22 March 2024, 06:37 | #16 |
Alien Bleed
Join Date: Aug 2022
Location: UK
Posts: 4,478
|
Why do you need double the address of something? Especially something like a symbol that has a runtime address that could be anywhere, what does double the address point at? It could be pointing at arbitrary memory, hardware or even nothing at all.
|
22 March 2024, 07:36 | #17 |
Registered User
Join Date: Sep 2017
Location: Kansas, USA
Posts: 329
|
*evil laugh* Sounds like the job for self-modifying code!
|
22 March 2024, 12:12 | #18 |
Registered User
Join Date: May 2022
Location: Canada
Posts: 140
|
1) Rotareneg: I personally hate self-modifying code, except on no-cache system like a Tandy CoCo, where it makes a lot of sense
2) Karlos: I never access the 'double memory address': the value is just used as a fast swap between two addresses. I'll try to explain with numbers to make my intention perhaps clearer. Values are in decimal, consider them absolute addresses: buffer 1 is at address 20 buffer 2 is at address 36 sum of addresses = 20 + 36 = 56 SUM=56 Say X is your pointer, initially starting on buffer 1. X=20 Now at every frame, you wish to alternate between the two buffers. The calculation would be: X=SUM-X This will make X swap between 20 and 36. Again just to be clear, this exercise is just for fun and understanding the inner workings. My question was essentially to see if this value (i.e.: adding two addresses together) could have been calculated at load-time by the loader, instead of being done at runtime by my code. |
22 March 2024, 15:11 | #19 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,491
|
I understand that you want the linker to solve the problem for you, but I think that using realtime constants the code is much simpler, more intuitive and faster
I would use something like this: Code:
lea buffer1,a0 lea (buffer2-buffer1,a0,a0.l),a1 .loop move.l a0,d0 move.l a1,a0 suba.l d0,a0 ; bra.b .loop buffer1 ds.b 16 buffer2 ds.b 16 a1 is a fast constant (which requires no relocation by LoadSeg and uses fewer cycles than a constant value). If instead you absolutely want an exe file that relocates a1 with a constant value it is possible, but the linker is not able to generate it for you. It's not a problem with LoadSeg or the Amiga Hunks, nothing in the relocation table prevents you from 'rearranging' the same longword in memory twice. So I can also create one for you by 'replacing' the linker job, but I don't think that's the purpose Furthermore, OS purists would tear me to pieces because it's a dirty trick.. |
22 March 2024, 15:47 | #20 |
Registered User
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 56
Posts: 2,047
|
No, this is not dirty trick. This is trick only.
Because most (or maybe all) Amiga assemblers dont has support for double relocation for same longword. Same code at absolute addresses will be assembled by Amiga assemblers. Then for me can be created for Amiga exe file too. Of course I dont see really good usage for this command, because code is too short for me. But maybe can be useful for something. Its minimum 2 bytes shortest (and 6 cycles fastest for 68000, if I remember timings) , than similar code. |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Double PAL / Double NTSC, oficially supported by WHDLoad... | Shoonay | project.WHDLoad | 3 | 15 May 2021 19:42 |
DOUBLE DRAGON II vs DOUBLE DRAGON 3 AMIGA TITLE MUSIC | ZEUSDAZ | Retrogaming General Discussion | 20 | 16 January 2021 13:29 |
Any way to avoid value change in memory address permanently | fstarred | Coders. General | 6 | 12 August 2020 18:51 |
List memory address range | solarmon | Coders. Scripting | 2 | 18 December 2019 15:31 |
NAT address | -Rob- | support.Other | 7 | 07 April 2008 00:06 |
|
|