Inline Assembly

Just starting out? Need help? Post your questions and find answers here.
LJ
Enthusiast
Enthusiast
Posts: 177
Joined: Wed Apr 30, 2003 4:00 pm

Inline Assembly

Post by LJ »

I'm intrigued by the Inline Assembly example called ASMInline.pb in the Examples folder. Has anyone written the "Hello World" program in Purebasic using part PB and part assembly? Are there any more simple examples of using assembly in Purebasic? Something simple that shows an "Include" command with some assembly language in Purebasic?

I've download FASM version 1.46 and an example code is (only 1.5K):

Code: Select all


; example of simplified Win32 programming using complex macro features

include '%include%/win32ax.inc'

.code

  start:
	invoke	MessageBox,HWND_DESKTOP,"Hi! I'm the example program!","Win32 Assembly",MB_OK
	invoke	ExitProcess,0

.end start
How can this code be pasted into Purebasic and then ran? Is there a way to "include" the win32ax.inc file in Purebasic?
Fred
Administrator
Administrator
Posts: 18351
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

Yes, just use the '!' mark before your assembly lines and you can do what you want with FASM.
LJ
Enthusiast
Enthusiast
Posts: 177
Joined: Wed Apr 30, 2003 4:00 pm

Error on Include

Post by LJ »

Hi Fred,

Wow that's awesome! I keep getting an error on the Include line that is "file not found". Fasm has an .ini file that tells it where the environmental variable for Include points to. I think this is the problem. How do I tell Purebasic to look in c:\fasm\INCLUDE\ for all the Win32.INC files?
LarsG
Enthusiast
Enthusiast
Posts: 713
Joined: Mon Jun 02, 2003 1:06 pm
Location: Norway
Contact:

Post by LarsG »

I guess you could always write:

Code: Select all

!include 'c:\fasm\include\win32ax.inc'
But then again.. I would know how it would behave when compiled to an exe..
(I'm really no asm-kinda guy.. ;))

-Lars

AMD Athlon XP2400, 512 MB RAM, Hercules 3D Prophet 9600 256MB RAM, WinXP
PIII 800MHz, 320 MB RAM, Nvidia Riva Tnt 2 Mach 64 (32MB), WinXP + Linux
17" iMac, 1.8 GHz G5, 512 MB DDR-RAM, 80 GB HD, 64 MB Geforce FX 5200, SuperDrive, OSX
LJ
Enthusiast
Enthusiast
Posts: 177
Joined: Wed Apr 30, 2003 4:00 pm

No

Post by LJ »

No, that didn't work either. Perhaps the inline assembly is only for things that don't involve using the "include" command. Perhaps one needs to create the source code in FASM, or NASM editor, and then interface it with Purebasic via the mechanism known as a "library" and not try to use an Include directly in the Purebasic editor?
Last edited by LJ on Wed Jun 18, 2003 5:36 am, edited 1 time in total.
LJ
Enthusiast
Enthusiast
Posts: 177
Joined: Wed Apr 30, 2003 4:00 pm

My First Assembly/PureBasic Hybrid

Post by LJ »

Code: Select all


; Don't forget to enable the 'Inline ASM support' feature in the compiler
; option window.
;
; Count Down (Assembly/PureBasic Hybrid Code) by Lance Jepsen


OpenConsole()                                  
ConsoleTitle ("Assembly Example")  

i8.l = 1
c8.l = 1

MOV i8, 100
MOV c8, 0

While i8 > 0
  If c8 = 10
    PrintN("")
    MOV c8, 0
    EndIf
    Print (""+Str(i8)+" ")
    SUB i8, 1
    ADD c8, 1
Wend

PrintN("")

PrintN("enter to quit")
quit$ = Input()

CloseConsole()

chris_b
Enthusiast
Enthusiast
Posts: 103
Joined: Sun Apr 27, 2003 1:54 am

Re: Error on Include

Post by chris_b »

LJ wrote:How do I tell Purebasic to look in c:\fasm\INCLUDE\ for all the Win32.INC files?
type set include=c:\fasm\include at the Windows command prompt to set the required environment variable.

(also in XP you can use Control Panel -> System -> Advanced -> Environment Variables. (can't remember if it's the same in '98 ))

However, when I try to compile !include '%include%/win32ax.inc'
in PB it finds the win32ax.inc but then stops with an "unexpected instruction" error.

Alternative method of opening a messagebox with inline assembly is:

Code: Select all

!extrn "__imp__MessageBoxA@16" as MessageBox:dword
PUSH 0
PUSH _caption
PUSH _message
PUSH 0
CALL [MessageBox]
RET
!_caption db "Win32 Assembly",0
!_message db "Hi! I'm the example program!",0
But regarding Win32 API functions I think I prefer the PureBasic way:

Code: Select all

MessageBox_(HWND_DESKTOP,"Hi! I'm the example program!","Win32 PureBasic",MB_OK)
As far as I can tell (which isn't very far when it comes to assembly language) the invoke thing is like the FASM equivalent to PureBasic's trailing-underscore-after-the-function-name method, so I don't know if there's any benfit to using the win32ax.inc stuff from within PureBasic.
LJ
Enthusiast
Enthusiast
Posts: 177
Joined: Wed Apr 30, 2003 4:00 pm

that's great!

Post by LJ »

That's great Chris, love your code. I don't fully understand it, wish I did. I'm going to start a thread in the Tricks and Tips about the Inline Assembler based on The Art of Assembly so that a newbie, like me, to Assembly can "Search" on the word "Assembly" and find lots of helpful information to get them started using PureBasic Inline Assembly. I sure could use your help. The idea is to create "Tutorials" in order of increasing complexity. Your code might be something like "Tutorial 5" or something. I've posted the first tutorial so you can get an idea. The format is fairly simple, basically its to get the text from The Art of Assembly (of course giving credit and the URL to the web site) on the commands your code will have, then post your PureBasic Inline Assembly code following the information. In case someone finds this thread and can't get your code to work, I've modified it to compile correctly by adding "!" in front of your lines of code. Again, if you have the time to explain to PureBasic Inline Assembly newbies like me how and why it works, it would be much appreciated. Thanks again - Lj

Code: Select all

!extrn "__imp__MessageBoxA@16" as MessageBox:dword 
! PUSH 0 
! PUSH _caption 
! PUSH _message 
! PUSH 0 
! CALL [MessageBox] 
! RET 
!_caption db "Win32 Assembly",0 
!_message db "Hi! I'm the example program!",0
chris_b
Enthusiast
Enthusiast
Posts: 103
Joined: Sun Apr 27, 2003 1:54 am

Post by chris_b »

The code I posted works fine if the 'Inline ASM support' option is checked.
Here's a slightly more PureBasic-friendly version, using ordinary strings instead of FASM labels:

Code: Select all

; Remember to enable Inline ASM support 

caption.s="Win32 Assembly"
message.s="Hi! I'm the example program!"

!extrn "__imp__MessageBoxA@16" as MessageBox:dword 
PUSH 0 
PUSH caption 
PUSH message 
PUSH 0 
CALL [MessageBox]

end
So the only required "!" is before the extrn command. I don't really know anything about the "extrn" directive, I'm an assembly newbie myself, my code is from an example that comes with the DOS/Windows Console version of FASM - I stumbled across it when I was looking for a way to open a messagebox without the win32ax.inc include and invoke command.

Also in my previous post I left a "RET" in by mistake, instead of using the normal "end" command.

As for your Assembly for Beginners thread - well, you probably already know more assembly than me but I'll certainly share any code snippets which I think will be helpful (at the moment I'm trying aquaint myself with assembly in order to conjure up a fast Boids style flocking algorithm for my game, but it's early days yet!)
LJ
Enthusiast
Enthusiast
Posts: 177
Joined: Wed Apr 30, 2003 4:00 pm

Interesting...

Post by LJ »

Hi Chris, thought you might like this.

Code: Select all

; Remember to enable Inline ASM support 
; OK =	000h
;OKCANCEL = 001h
;ABORTRETRYIGNORE = 002h
;YESNOCANCEL  =  003h
;YESNO  = 004h
;RETRYCANCEL  =  005h
;ICON ERROR = 010h
;ICON QUESTION =  020h
;ICON WARNING  = 030h
;ICON INFORMATION = 040h

;OK = 01h
;CANCEL  = 02h
;ABORT =  03h
;RETRY  =  04h
;IGNORE =  05h
;YES   =  06h
;NO  =  07h
;CLOSE =  08h
;HELP  =  09h


caption.s="Win32 Assembly" 
message.s="Hi! I'm the example program!" 

!extrn "__imp__MessageBoxA@16" as MessageBox:dword 

PUSH 001h 
PUSH caption 
PUSH message 
PUSH 0 
CALL [MessageBox] 

End
Notice that the message box is a 16 bit dword that holds 4 entries, and those 4 entries are then pushed. By using the different numbers above, you can create a window with different things, try changing the 001h.
Post Reply