After playing with the binary editor that I would say works but is not fully
accessible on Visual studio. I got to wondering if my assembler program I
wrote as a fruit basket program would still work now. Note if you don't
know about the fruit basket program I came up with the idea from a Delphi
presentation when it was brand new. They showed how they could make a list
program that added and deleted items in a few mouse clicks. I brought it to
the blind programming list and it went wild. Jamal now has a github page
with a bunch of versions. I didn't keep all mine but I just found my java,
lisp, and the reason I am mentioning this one my assembler version. That's
right I have an assembler version of the fruit basket program. I had it on
an old back up drive and get this the executable still runs even though it
was wrote under XP service pack 3 and written in assembler.
To be clear the idea of the Fruit basket program was to make a dialog base
program with one list, an add and a delete button and I think Jamal added
exit buttons later but the idea was to show anyone how to make that simple
program in any language. Just search for fruit basket on Github with
the developer as name Jamal and you will find his page. Even though I came
up with the original project they seem to have left me out of it. Shrug I
am not one that asks for credit for anything or Jaws would have put my name
in the original Visual studio windows forms scripts.
I learned assembler early on my commadore Vic-20 and used it in college for
my engineering classes and more recental for some hardware projects Iam
working on.
Anyway I wanted to send this so others could have fun with assembler in
windows if they want to. The last time I accessed this old drive file was
2006 so this was written before that.
Here is my original post to the blind programming list of the time and I
edited it a bit to be more readable and to have current links for goasm.
----Old edited post from blind programming----
Ok we all know I can't spell and my grammar sucks. So since
computers seem to be the only thing that understands me. I
decided I would do the fruit Basket demo program in assembler.
I found that windows assembler is fun and easy and cheap.
When I started this I mentioned it to Sina and after talking to him I came
up with a few requirements
1. No external source files like RC files so only one .asm should make
the program
2. I want the tools to be free
3. The tools should have a decent amount of documents.
4. I will not use MASM (Microsoft asm) because it has high level
instructions like while, if, do etc... What fun is ASM if you don't use jz
jnz etc...
Coding in assembler for windows is a lot like coding with
WIN32 for c and c++. You do not call the old DOS init 21 or
things of that sort rather you dive directly into the DLL
files which means you have full access to everything any
programmer has access to and you have it at a much lower
level.
So with all this in mind I went out looking on line for a
tool that would meet my needs. NASM would work but there
was just to much unclear information out there. So I
decided on an assembler called GoAsm. The only problem with
GoAsm is that the debugger for it on XP is not free. It is
only 47$ but I did not buy it. I wrote this with out a
debugger so that means I rebooted a lot and had a lot of
lagging processes but I got it done with out a debugger.
Now you could use any of the assembler debuggers out there so the
tools are still free I just didn't bother because I had a
free linker and free assembler. You can get the goasm.exe
and golink.exe at this site.
NOTE update link for 2022:
The link changed so I am putting the new link. You need to download both
the goasm and golink zip files and put them in a folder and add that folder
to you r environment path. Oh and the comment about the debugger being not
free. That is no longer the case. You can get a debugger as well from this
page if you want it. Here is the new link:
http://www.godevtool.com/
I called my program fab (fruit Assembler basket)
So with the two tools above I assembled and linked it as
follows.
goasm fab.asm
golink fab.obj kernel32.dll user32.dll
NOTE for 2022 the above goasm command on a windows 10 machine with the new
goasm 64 bit assembler is:
Goasm /x86 fab.asm
It was that simple.
Note for 2022:
If you want to convert my code to 64 bit so you don't have to use /x86 it is
not hard and when you download goasm and golink they have a file that has
things you have to do to convert it. I might convert it but for now I have
it working again.
Below is the original code that still works just put it in a file called
fab.asm and follow the above instructions and you have an old school asm
program.
The following is the code in full and it is well commented
if you want to know how the program works.
; file starts here
;Fruit basket program in GoAsm assembler.
DATA SECTION
;Messages handled defined to make code clearer.
; You could just use the hex but I wanted to see if this worked
WM_DESTROY EQU 2h
WM_INIT EQU 110h
WM_COMMAND EQU 111h
ALIGN 4
stringMem DD ? ;holder for passing string between controls
ALIGN 4 ;just to emphasise this must be dword aligned
;*********************** here is the dialog template for the dialog
DIALOG_TEMPLATE DD 10000000h |0C00000h |800h |40h| \
80h |80000h +20000h
;style WS_VISIBLE+WS_CAPTION+DS_CENTER+DS_SETFONT
; DS_MODALFRAME+WS_SYSMENU+WS_MINIMIZEBOX
DD 0 ;extended style
DW 5 ;no. items in dialog box
DW 0 ;top left x position
DW 0 ;top left y position
DW 177 ;box width
DW 130 ;box height
DW 0 ;menu array (no menu)
DW 0 ;class array (use default)
DUS 'Fruit Basket GoAsm Demonstration',0
;title (DUS causes assembler to convert string
;to Unicode as required by Windows)
DW 10 ;font point size
DUS 'Times New Roman',0
;you can change the font using eg. Arial or Sans Serif
;*********************************** make a box for the following group
ALIGN 4 ;must be dword aligned
DD 50800000h
;(WS_CHILD+WS_VISIBLE+WS_BORDER)
DD 0 ;extended style
DW 6 ;control top left x position
DW 6 ;control top left y position
DW 50 ;control width
DW 23 ;control height
DW 100 ;control identifier
DW -1 ;look at next for class
DW 82h ;Static control
DUS 'Enter fruit:',0
DW 0 ;elements to send to DlgProc (none)
;*********************************** next control
ALIGN 4 ;must be dword aligned
DD 50810040h
;(WS_CHILD+WS_VISIBLE +ES_LEFT+WS_BORDER+WS_TABSTOP+ES_AUTOVSCROLL)
DD 0 ;extended style
DW 57 ;control top left x position
DW 6 ;control top left y position
DW 120 ;control width
DW 23 ;control height
DW 101h ;control identifier
DW -1 ;look at next for class
DW 81h ;edit control
DUS '',0
DW 0 ;elements to send to DlgProc (none)
;*********************************** next control
ALIGN 4 ;must be dword aligned
DD 50810000h ;
;(WS_CHILD+WS_VISIBLE+WS_BORDER+WS_TABSTOP)
DD 0 ;+4 extended style
DW 6 ;+8 control top left x position
DW 31 ;+A control top left y position
DW 50 ;+C control width
DW 23 ;+E control height
DW 102h ;+10 control identifier
DW -1 ;+12 look at next for class
DW 80h ;+14 button control
DUS '&Add',0
DW 0 ;elements to send to DlgProc (none)
;*********************************** next control
ALIGN 4 ;must be dword aligned
DD 50810000h ;
;(WS_CHILD+WS_VISIBLE+WS_BORDER+WS_TABSTOP)
DD 0 ;extended style
DW 6 ;control top left x position
DW 55 ;control top left y position
DW 50 ;control width
DW 23 ;control height
DW 103h ;control identifier
DW -1 ;look at next for class
DW 80h ;button control
DUS '&Delete',0
DW 0 ;elements to send to DlgProc (none)
;*********************************** next control
ALIGN 4 ;must be dword aligned
DD 50810001h
;(WS_C HILD+WS_VISIBLE+WS_BORDER+LBS_NOTIFY+WS_TABSSTOP)
DD 0 ;extended style
DW 57 ;control top left x position
DW 31 ;control top left y position
DW 120 ;control width
DW 76 ;control height
DW 104h ;control identifier
DW -1 ;look at next for class
DW 83h ;listbox control
DUS 'First item',0
DW 0 ;elements to send to DlgProc (none)
;A good buy message to show how to pass it to message box.
ALIGN 4
GOODBYE_MESSAGE DB "Goodbye from the Fruit basket!",0
;*******************************************************************
;* CODE
;*******************************************************************
CODE SECTION
ALIGN 4
START:
PUSH 0
CALL GetModuleHandleA ;get handle to this process in eax
;****************************** now create the dialog box
PUSH 0 ;initialisation value (not used)
PUSH ADDR DlgProc ;pointer to dialog procedure
PUSH 0 ;this dialog has desktop as parent
PUSH ADDR DIALOG_TEMPLATE ;template in the file itself
PUSH EAX ;handle to this process from GetModuleHandleA
CALL DialogBoxIndirectParamA ;this does not return until dialog closed
PUSH 0 ;exit code zero
CALL ExitProcess ;never returns from here
;******************************************************* DIALOG PROCEDURE
;This uses FRAME..ENDF to establish a local data and to get the parameters
;
DlgProc FRAME hDlg,uMsg,wParam,lParam
USES EBX,EDI,ESI ;save ebx,edi,esi as required by Windows (safety
only)
MOV EAX,[uMsg] ;get message
CMP EAX,WM_INIT ;See if dialog is initializing.
JNZ >endInit ;no, jump to next colon
CALL INITIALISE_DIALOG
ret
endInit:
CMP EAX,WM_COMMAND ;see if WM_COMMAND message
JNZ >endDestroy
CMP W[wParam],1h ;Enter button
JNZ >endEnter
call ADD
call EditFocus
ret
endEnter:
CMP W[wParam],102h ;Add button
JNZ >endAdd
call ADD
call EditFocus
ret
endAdd:
CMP W[wParam],103h ;Delete button
JNZ >endDelete
call delete
call EditFocus
ret
endDelete:
CMP W[wParam], WM_DESTROY
JNZ >endDestroy ;no
;Dialog exiting so say good bye with Message box.
PUSH 40h ;information and ok button
PUSH 'GoodbyeDialog' ;title
PUSH ADDR GOODBYE_MESSAGE ;main body text
PUSH [hDlg] ;owner (this dialog)
CALL MessageBoxA
PUSH 1,[hDlg]
CALL EndDialog ;end the dialog
endDestroy:
XOR EAX,EAX ;return zero as required
RET
ENDF
;
INITIALISE_DIALOG:
USEDATA DlgProc ;use the local data held in the DlgProc frame
;This sets the edit box to take only 32 characters.
PUSH 0 ;Not used.
PUSH 32 ; amount of characters.
push 197 ;EM_LIMITTEXT
PUSH 101h ;Control ID
PUSH [hDlg]
call SendDlgItemMessageA
or EAX,EAX
RET
ADD:
;Create the memory for the string to pass
PUSH 4h ;flag read and write access
PUSH 1000h ;commit memory flag
PUSH 8800h ;size of memory to be committed
PUSH 0 ;where to put memory
CALL VirtualAlloc
OR EAX,EAX ;see if false finish
JZ >.noMemory ;if fail
MOV [stringMem], EAX ;Save the pointer to the memory
;Get the text from the edit box.
PUSH [stringMem] ;pointer for the string
PUSH 8000h ;Size of memory minus a character for null
PUSH 0Dh ;WM_GETTEXT
PUSH 101h ;ID
PUSH [hDlg]
call SendDlgItemMessageA
CMP EAX, 0 ; did we get text or is it blank?
JZ >.clearMemory ;if no text
;Now lets add the item to list box
PUSH [stringMem] ;Our memory
PUSH 0 ;Not used
PUSH 180h ;LB_ADDSTRING
PUSH 104h ;List control ID
PUSH [hDlg]
call SendDlgItemMessageA
call ClearEdit ;Clear edit box
.clearMemory
PUSH 8000h ;release flag
PUSH 0 ;all memory to go
PUSH [stringMem] ;address of memory area
CALL VirtualFree
OR EAX,EAX ;see if false finish
JZ >.noMemory ;if fail
.noMemory
ret
delete:
PUSH 0 ;Not used
PUSH 0 ;Not used
PUSH 188h;LB_GETCURSEL
PUSH 104h ;ID
PUSH [hDlg]
call SendDlgItemMessageA
add EAX , 1
OR EAX,EAX
JNZ >.selected ;if something selected
PUSH 40h ;information and ok button
PUSH 'Warning'
PUSH 'Nothing selected, Please select an item and try again.'
PUSH [hDlg] ;owner (this dialog)
CALL MessageBoxA
ret
.selected
SUB EAX, 1
PUSH 0 ;Not used
PUSH EAX ;selected item from last call
PUSH 182h; delete string listbox
PUSH 104h
PUSH [hDlg]
call SendDlgItemMessageA
ret
ClearEdit:
PUSH 0 ;Clear text
PUSH 0 ;Not used
PUSH 0Ch ;WM_SETTEXTPUSH 101h
PUSH 101h ;Edit ID
PUSH [hDlg]
call SendDlgItemMessageA
ret
EditFocus:
PUSH 101h
PUSH [hDlg] ;ptr to dialog
CALL GetDlgItem ;get the handle to the control in eax
;EAX is now the edit control
PUSH 1 ;true flag to say use next arguement as control
PUSH EAX ;edit control to get focus
PUSH 28h ;DM_NEXTDLGCTL
PUSH [hDlg]
call SendMessageA
ret