News:

Download Pelles C here: http://www.pellesc.se

Main Menu

Recent posts

#1
Assembly discussions / Extracting binary data with Po...
Last post by Vortex - Yesterday at 10:06:02 AM
Simple method to extract binary executable data with Poasm. The procedure WriteFileToDisc saves the code between the two labels, MsgBox and start. This method is useful to call assembly code from languages like RapidQ Basic with no inline assembly support.

.386
.model flat,stdcall
option casemap:none

ExitProcess PROTO :DWORD

WriteFileToDisc PROTO :DWORD,:DWORD,:DWORD

.data

fname       db 'MsgBox.bin',0

.code

MsgBox:

    call    delta

delta:

    pop     edx
    mov     eax,OFFSET delta
    sub     edx,eax
    lea     eax,[edx+capt]
    lea     ecx,[edx+msg]

;   call    MessageBox

    push    0
    push    eax
    push    ecx
    push    0
    call    DWORD PTR [esp+20]
   
    retn    16

capt    db 'Hello',0
msg     db 'This is a test.',0

start:

ProcLen EQU start-MsgBox

    invoke  WriteFileToDisc,ADDR fname,\
            MsgBox,ProcLen
           
    invoke  ExitProcess,0

END start

Running the executable, it creates the file MsgBox.bin

RapidQ Basic code calling the embedded binary data :

$APPTYPE GUI

DIM s AS STRING

DIM pMessageBox as INTEGER

DECLARE FUNCTION CallWindowProc LIB "user32" ALIAS "CallWindowProcA" _
                 (Proc AS LONG, p1 AS LONG, p2 AS LONG, p3 AS LONG, _
                 p4 AS LONG) AS LONG

DECLARE FUNCTION GetProcAddress LIB "kernel32" ALIAS "GetProcAddress" (hModule AS LONG, lpProcName AS STRING) AS LONG
DECLARE FUNCTION LoadLibrary LIB "kernel32" ALIAS "LoadLibraryA" (lpFileName AS STRING) AS LONG

DefInt ptrMsgBox

FUNCTION MsgBox1(pointer As Long) As Long
    Result=CallWindowProc(ptrMsgBox,pointer,0,0,0)
END FUNCTION

$RESOURCE ResourceName AS "MsgBox.bin"

DIM Mem AS QMEMORYSTREAM

Mem.ExtractRes(Resource(0))
Mem.Position=0
s=Mem.ReadBinStr(Mem.Size)

ptrMsgBox=varptr(s)

pMessageBox = GetProcAddress(LoadLibrary("user32.dll"), "MessageBoxA")

MsgBox1(pMessageBox)

Compiling the RapidQ code :

RC.EXE -LC:\Rapidq\lib MBox.bas
#2
Work in progress / Re: Code Density Comparison of...
Last post by John Z - July 25, 2026, 09:04:34 AM
So - what actual hardware or hardware emulator is running your ϕEngine?
Using ARM?, QEMU,  custom FPGA?

John Z
#3
ARM64 discussions / Re: Not frustrated enough? Too...
Last post by PabloMack - July 24, 2026, 09:42:57 PM
I think it is a good thing to understand (and even discuss) the limitations of everything you use. Otherwise there will likely never be improvement.
#4
ARM64 discussions / Re: Not frustrated enough? Too...
Last post by TimoVJL - July 24, 2026, 08:10:53 PM
Pelles C C-compiler support ARM64, why not just use it.
An assembler is just for making some useful functions using CPU in best way.
#5
ARM64 discussions / Re: Not frustrated enough? Too...
Last post by PabloMack - July 24, 2026, 04:21:24 PM
The gymnastics that ARM64 has to go through to come up with these string addresses is amazingly bad.
#6
Work in progress / Code Density Comparison of two...
Last post by PabloMack - July 23, 2026, 04:35:45 AM
I just rewrote an assembly function for the Pelles C assembler that compares two unsigned 24-bit integers. The function returns 1 for greater, 0 for equal and -1 for less than. I thought some of you might find it interesting. The x64 version was 45 bytes in size. I wrote a ϕEngine version and it is 15 bytes, only 1/3 the size. But this should not be surprising since ϕEngine can process 3-byte integers natively. Here is the source code:

 ⅅCPU Eng32
ut_cmp‡: ⅅPBeg
    ld     ⓊQ0,ut:(Ⓡ0)
    cmp    ⓊQ0,ut:(Ⓡ1)
    s.A*   Ⓒ0,ⓊQ0
    s.B*   Ⓒ0,ⓈQ0
    rts
 ⅅPEnd

Notice that the processing has to be done in a 32-bit register (ⓊQ0) which also is used to hold the return value. The two source values are extended during the loads so there are no separate conversion routines. The second load is part of the compare instruction. Most of the code is for producing a return value from the flags that are set by the compare. Since this operation can be done inline cheaper than even just the setup for function call, the function would actually never be needed in ϕPPL or ϕAsm.
#7
General discussion / Re: Pelles C and Windows Defen...
Last post by John Z - July 22, 2026, 11:20:48 PM
Yes, Pelles C is very flexible that way.

However the Windows 'Protections' are not limited to programs installed just into the Windows preferred directories.  When enabled they are system wide.  If one maxes out the protections probably the only place to get programs is the M$S windows store....

John Z
#8
Work in progress / Re: High Performance 64-bit CP...
Last post by PabloMack - July 22, 2026, 08:43:36 PM
Quote from: John Z on March 10, 2024, 04:32:49 PMI applaud your ambition!  Other than my experience with Xilinx FPGA, many years ago, it is way way out of my zone.  But I look forward to trying it someday.

John Z

Are you limiting your possible collaborators by requiring LinkedIn? I stayed away from it, and especially after it became an arm of Micro$oft...

I share your sentiment about LinkedIn and MicroSoft. 😁
#9
Work in progress / Update on ϕEngine
Last post by PabloMack - July 22, 2026, 08:37:34 PM
I just read my post of April 16, 2020. Since then I have made many modifications and now the architecture defines both a 32-bit sub-architecture (called ϕEng32) with 32-bit address spaces and a 64-bit sub-architecture (called ϕEng64) with 64-bit address spaces. The two sub-architectures share the same instruction set. The reason why ϕEngine is able to do that when most others can't (including x86, ARM and RISC-V) is because all address computations are done in special Address Registers and not integer registers. That frees the integer registers to support all types and sizes for both sub-architectures. ϕEngine is more orthogonal than x86 in that you can directly use all sub-parts of all registers as registers themselves. x86 can only do this to a very limited extent such as al and ah being the lower and upper halves of ax. But you can't use R8~R15 that way. And you can't even directly reach the 3rd or 4th order bytes in eax or even the upper half of eax as a 16-bit register. But you have direct access to all of them in ϕEngine. Not only that, you can reach all registers as 1, 2, 3, 4, 5, 6, 7 or 8-byte integers directly. One thing that makes ϕEngine far easier to program is that data size extension it built into the loads and stores so you don't need separate conversion instructions. They are built into the basic operations.

The focus of ϕEngine has changed from performance to memory efficiency for both code and data. ϕEngine processors consistently have denser code and need less memory to perform the same functions as other processors. All of the SW tools are written in C. I have once again begun to port code from WATCOM to Pelles. I waited a long time for WATCOM to support AMD64 and have decided that Pelles is the way to go.

I just finished rewriting a function I use a lot in the tool chain to zero-extend any integer to one of a larger size. After writing it in Pelles C assembly I wanted to see how much easier it was to write in ϕEngine assembly and compare the code densities. The AMD64 version is 43 bytes and the ϕEngine version did it in 27 bytes.

I assembled the x64 version to produce an assembly listing. It has a lot of space in it to make the columns aligned. I saved this same file into the ϕText format that I use for storing all ϕ System documentation and source code. The Pelles C listing takes up 3053 bytes while the ϕText encoded file occupies 1361 bytes. That is less that 45% the storage requirements.
#10
General discussion / Re: Pelles C and Windows Defen...
Last post by Vortex - July 22, 2026, 03:27:16 PM
Timo is right. For example, Pelles C can be installed on the root partition, C:\PellesC