Post Reply 
Assembler, but not at all
09-21-2023, 09:26 AM
Post: #1
Assembler, but not at all
I know that the decision has already been made that there won't be any possibility to run machine code (assembler) on the HP Prime. I understand the risks associated with this, and it's clear to me that opening low-level access is not advisable in this case.

However, what if we could find a compromise?
All of this is about performance, and performance is needed in algorithms. Algorithms mainly operate on lists (or possibly arrays, which can be mapped to lists anyway). We don't want assembler access to dig into the operating system's memory or manipulate forbidden objects, but rather to use it for fast calculations. Access to a limited memory area (reserved for this purpose) would be sufficient. This memory area could be dedicated to an object, let's call it NativeList, and possibly to text string (which already exists in PPL).

NativeList would be low-level, containing only 32-bit integers (as ARM standardly operates). The string, on the other hand, would remain as it is, essentially also a list but with 16-bit values.

In addition, a pseudo-assembler would need to be created, which would have a limited number of ARM assembler instructions (common for G1 and G3), but with the additional requirement that during code compilation, for all memory read/write operations, it would add a few extra verification commands to ensure that the read and write operations stay within the allowed memory area.

So, we could select a few ARM instructions that allow memory read and write operations and secure them, while the remaining ARM instructions like arithmetic, bitwise operations, etc., could be directly compiled into machine code as they don't introduce sabotage risks. Alternatively, we could consider the stack since it's theoretically also a read and write operation to memory.

However, it's crucial that all of this compiles into a native procedure in machine code and is possible to run for the specified object from the PPL level.

For instance, for a memory read operation in the list:
Code:
    ldr r1, [mem_addr]

After compilation, it would look something like this:
Code:
    ldr r1, =mem_addr
    ldr r2, =0x1000      @ load lower bound of the range (set by PPL environment)
    ldr r3, =0xFFFF      @ load upper bound of the range (set by PPL environment)
    cmp r1, r2           @ compare the address in r1 with the lower bound
    blo error_handler    @ if address < lower bound, go to the error handler
    cmp r1, r3           @ compare the address in r1 with the upper bound
    bhi error_handler    @ if address > upper bound, go to the error handler
    ldr r1, [r1]         @ you can continue reading data from memory here because the address is within the allowed range

And perhaps here, there should be some push and pop instructions to secure the modified registers.

Actually, this can be implemented as a subroutine in asm, and for each ldr call this subroutine and pass the arguments in it (an index instead of an address).
A similar protection can be done for memory writes, and it would actually create a sophisticated solution that solves all performance issues on the HP Prime, providing 95% native CPU performance in areas where performance is critical. Of course, the assumption is that the program is still written in PPL, but individual procedures are added in ARM and called, for example, with the EXEC command.

From the PPL level, a created NativeList or string should be stored in a variable and passed as an argument (3 examples):

Code:
#ASM armRoutine1
.
.
#END

EXPORT ARMTEST1()
BEGIN
  LOCAL nlst, result;
  nlst := MAKENATIVELIST(0,512);         // Create a native list containing 512 32-bit cells initialized with values of 0.
  result := EXEC(armRoutine1, nlst);     // Execute the procedure on this list and retrieve the modified list.
END;

Code:
#ASM armRoutine2
.
.
#END

EXPORT ARMTEST2()
BEGIN
  LOCAL lst, nlst, result;
  lst := MAKELIST(X, X, 1, 100);         // Create a PPL list and initialize it with values from 1 to 100.
  nlst := MAKENATIVELIST(lst);           // Create a native list initialized according to the provided PPL list (containing 100 32-bit cells with values from 1 to 100).
  result := EXEC(armRoutine2, nlst);     // Execute the procedure on this list and retrieve the modified list.
END;

Code:
#ASM armRoutine3
.
.
#END

EXPORT ARMTEST3()
BEGIN
  LOCAL str, result;
  str := "STRING TO MANIPULATE";
  result := EXEC(armRoutine3, str);      // Execute the procedure on this string and retrieve the modified string.
END;

If someone needs an array, it can be simulated using a list with the mla command (ARM), for calculation of coordinates and mapping to a specific memory area. Alternatively, you can also use a built-in subroutine for such purposes.

Writing the compiler itself is relatively straightforward because it involves mapping ARM instructions and their arguments to their binary form (which is readily available).

Of course, this is a loose proposal. It can be further refined, discussed, and potentially implemented differently, but my intention was to present the general principles of this concept, which could prove to be a game-changer. Such a solution would unlock the potential of the HP Prime and undoubtedly place it ahead of other calculators.

@Jeff,
What do you think about this?
If such a mechanism were to be created, we could independently start creating functions like the ones we discussed, such as a customized string REPLACE, tailored to specific needs.

Piotr
Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
Assembler, but not at all - komame - 09-21-2023 09:26 AM
RE: Assembler, but not at all - komame - 09-22-2023, 03:50 AM
RE: Assembler, but not at all - jte - 09-22-2023, 09:03 PM
RE: Assembler, but not at all - komame - 09-25-2023, 05:24 PM
RE: Assembler, but not at all - jte - 09-26-2023, 07:24 AM
RE: Assembler, but not at all - komame - 10-11-2023, 09:43 AM
RE: Assembler, but not at all - John Keith - 10-11-2023, 02:20 PM
RE: Assembler, but not at all - komame - 10-11-2023, 04:36 PM
RE: Assembler, but not at all - jte - 10-12-2023, 12:08 AM
RE: Assembler, but not at all - jte - 09-22-2023, 09:19 PM
RE: Assembler, but not at all - John Keith - 10-11-2023, 10:41 PM
RE: Assembler, but not at all - komame - 10-12-2023, 03:31 AM
RE: Assembler, but not at all - Claudio L. - 10-14-2023, 08:52 PM
RE: Assembler, but not at all - parisse - 10-12-2023, 06:55 AM
RE: Assembler, but not at all - komame - 10-12-2023, 07:13 AM
RE: Assembler, but not at all - parisse - 10-12-2023, 12:15 PM
RE: Assembler, but not at all - John Keith - 10-12-2023, 08:40 PM
RE: Assembler, but not at all - parisse - 10-12-2023, 12:49 PM
RE: Assembler, but not at all - parisse - 10-13-2023, 05:36 AM
RE: Assembler, but not at all - komame - 10-13-2023, 01:16 PM
RE: Assembler, but not at all - komame - 10-14-2023, 04:12 PM
RE: Assembler, but not at all - parisse - 10-13-2023, 04:56 PM
RE: Assembler, but not at all - parisse - 10-15-2023, 06:21 AM
RE: Assembler, but not at all - Claudio L. - 10-18-2023, 02:46 AM
RE: Assembler, but not at all - komame - 10-18-2023, 05:41 PM
RE: Assembler, but not at all - Claudio L. - 10-19-2023, 02:54 AM
RE: Assembler, but not at all - komame - 11-01-2023, 07:06 AM
RE: Assembler, but not at all - dlidstrom - 11-12-2023, 07:57 PM
RE: Assembler, but not at all - komame - 11-13-2023, 02:07 PM
RE: Assembler, but not at all - komame - 02-19-2024, 06:21 PM



User(s) browsing this thread: 2 Guest(s)