News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

PBCC50 assembler playpen.

Started by hutch--, December 20, 2009, 05:02:45 PM

Previous topic - Next topic

hutch--

I have recently been posting some tutorial level examples in the PB peer forum but unfortunately the lingering dead have struck again so I will post the examples here where assembler programmers are protected from the idiot fringe.

This example is a very simple empty console application designed primarily for developing and testing assembler subs and functions in PowerBASIC. It is aimed at much the same level of simplicity as a MASM console application where you can concentrate on the algo design without having to climb over the normal mountain of GUI code to get it up and going. The template prototypes a number of simple conversions directly out of MSVCRT

Here is the PBCC template.


#IF 0  ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    Build with PBCC50

    FUNCTION LIST
        1. cout     console display with C escape support
        2. pause    wait for a key press to continue
        3. sstr     convert a SIGNED integer to a basic string
        4. ustr     convert an UNSIGNED integer to a basic string
        5. atoi     convert a string to an UNSIGNED integer
        6. atol     convert a string to a SIGNED integer

#ENDIF ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

FUNCTION PBmain as LONG

    #REGISTER NONE

    LOCAL svar as LONG
    LOCAL uvar as DWORD

    cout "\n\tTestbed for Assembler Programming in\n\tthe PowerBASIC Console Compiler PBCC50\n\n"

  ' ---------------------------------------------
  ' conversion tests string to integer to string
  ' NOTE
  ' you only use these functions on 32 bit values
  ' ---------------------------------------------
    svar = atol("-12345678")        ' ascii to LONG conversion
    longint$ = sstr(svar)           ' LONG to ascii conversion
    cout longint$

    uvar = atoi("4000000000")       ' ascii to DWORD conversion
    uint$ = ustr(uvar)              ' DWORD to ascii conversion
    cout uint$

    pause

    FUNCTION = 0

End FUNCTION

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    DECLARE FUNCTION cc_out CDECL LIB "MSVCRT.DLL" ALIAS "puts" (BYVAL ptxt AS DWORD) AS DWORD

SUB cout(a$)

  ' ***** Supported escapes *****
  ' \0 = ascii zero             0
  ' \t = tab                    9
  ' \n = newline               10
  ' \r = carriage return       13
  ' \q = double quote          34
  ' \\ = backslash             92
  ' *****************************

    #REGISTER NONE

    LOCAL src as DWORD
    LOCAL dst as DWORD
    LOCAL sln as DWORD

    src = StrPtr(a$)

    ! mov esi, src
    ! mov edi, src

  stlp:
    ! mov al, [esi]
    ! add esi, 1

    ! cmp al, "\"
    ! jne nxt

' ¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤

    ! cmp BYTE PTR [esi], "n"
    ! jne lb1
    ! add esi, 1
    ! mov BYTE PTR [edi], 10
    ! add edi, 1
    ! jmp stlp
  lb1:

    ! cmp BYTE PTR [esi], "r"
    ! jne lb2
    ! add esi, 1
    ! mov BYTE PTR [edi], 13
    ! add edi, 1
    ! jmp stlp
  lb2:

    ! cmp BYTE PTR [esi], "t"
    ! jne lb3
    ! add esi, 1
    ! mov BYTE PTR [edi], 9
    ! add edi, 1
    ! jmp stlp
  lb3:

    ! cmp BYTE PTR [esi], "0"
    ! jne lb4
    ! add esi, 1
    ! mov BYTE PTR [edi], 0
    ! add edi, 1
    ! jmp stlp
  lb4:

    ! cmp BYTE PTR [esi], "\"
    ! jne lb5
    ! add esi, 1
    ! mov BYTE PTR [edi], 92
    ! add edi, 1
    ! jmp stlp
  lb5:

    ! cmp BYTE PTR [esi], "q"
    ! jne lb6
    ! add esi, 1
    ! mov BYTE PTR [edi], 34
    ! add edi, 1
    ! jmp stlp
  lb6:

' ¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤

  nxt:
    ! mov [edi], al
    ! add edi, 1
    ! test al, al
    ! jnz stlp

    ! sub edi, src
    ! mov sln, edi

    cesc$ = left$(a$,sln)

    cc_out StrPtr(cesc$)

END SUB

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    MACRO INPUT_HANDLE  = -10&
    DECLARE FUNCTION kbflush LIB "KERNEL32.DLL" ALIAS "FlushConsoleInputBuffer" ( _
                     BYVAL hConsoleInput AS DWORD) AS LONG
    DECLARE FUNCTION hStdIn LIB "KERNEL32.DLL" ALIAS "GetStdHandle" ( _
                     BYVAL nStdHandle AS DWORD) AS DWORD
    DECLARE FUNCTION SysYield LIB "KERNEL32.DLL" ALIAS "Sleep" ( _
                     BYVAL msWait AS DWORD) AS LONG
    DECLARE FUNCTION keypress CDECL LIB "MSVCRT.DLL" ALIAS "_kbhit" () as DWORD
    DECLARE FUNCTION putz CDECL LIB "MSVCRT.DLL" ALIAS "puts" (BYVAL ptxt AS DWORD) AS DWORD

' -------------------------------------------

SUB pause()

    txt$ = "Press any key to continue ...."
    putz StrPtr(txt$)
    kbflush hStdIn(INPUT_HANDLE)

  lbl0:
    SysYield 20
    keypress
    ! test eax, eax
    ! jz lbl0

END SUB

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    DECLARE FUNCTION ltoa CDECL LIB "MSVCRT.DLL" ALIAS "_ltoa" ( _
                     ByVal lval as LONG,ByVal pstr as DWORD,ByVal radix as DWORD) as DWORD

' -------------------------------------------

FUNCTION sstr(ByVal lval as LONG) as STRING

    LOCAL astring as ASCIIZ * 32

    ltoa(lval,VarPtr(astring),10)

    FUNCTION = astring

End FUNCTION

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    DECLARE FUNCTION c_ultoa CDECL LIB "MSVCRT.DLL" ALIAS "_ultoa" ( _
                     ByVal uint as DWORD,ByVal pstr as DWORD,ByVal radix as DWORD) as DWORD

' -------------------------------------------

FUNCTION ustr(ByVal uint as DWORD) as STRING

    LOCAL astring as ASCIIZ * 32

    c_ultoa(uint,VarPtr(astring),10)

    FUNCTION = astring

End FUNCTION

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    DECLARE FUNCTION c_atoi CDECL LIB "MSVCRT.DLL" ALIAS "atoi" (ByVal ptxt as DWORD) as DWORD

FUNCTION atoi(number$) as DWORD

    FUNCTION = c_atoi(StrPtr(number$))

End FUNCTION

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    DECLARE FUNCTION c_atol CDECL LIB "MSVCRT.DLL" ALIAS "atol" (ByVal ptxt as DWORD) as LONG

FUNCTION atol(number$) as LONG

    FUNCTION = c_atol(StrPtr(number$))

End FUNCTION

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

frktons

Hi Hutch,

unfortunately  at the moment I'm unable to understand
what you have produced, but my IT instinct tells me it is a real
neat and good stuff.

I'll try to study it  and learn something from it.

My intuition is that it can be used to learn some ASM code in a simplified context.

Thanks a lot for your patience.

Frank
Mind is like a parachute. You know what to do in order to use it :-)

hutch--

Frank,

If you own one of the PB compilers this style of code works well and it makes learning assembler programming a bit easier for people with a basic background. The biggest problem for anyone coming from another language is to remove enough of the level of assumption to try doing things in very basic ways but in this case the language handles true low level code if you can get the swing of it.

I am currently writing a complex project in PB which generates MASM code and it is the right language to do this as it has exceptional string handling which is well suited for code generation and while there is not much asm in it, these code generators do work well.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

frktons

Quote from: hutch-- on April 19, 2010, 01:17:56 AM
Frank,

If you own one of the PB compilers this style of code works well and it makes learning assembler programming a bit easier for people with a basic background. The biggest problem for anyone coming from another language is to remove enough of the level of assumption to try doing things in very basic ways but in this case the language handles true low level code if you can get the swing of it.

I am currently writing a complex project in PB which generates MASM code and it is the right language to do this as it has exceptional string handling which is well suited for code generation and while there is not much asm in it, these code generators do work well.

I totally agree. In fact this will be my main path for learning some ASM for now.

Frank
Mind is like a parachute. You know what to do in order to use it :-)