Hello,
I'd like to learn to program either the 80x86 (i think) windows/intel asm, or IA32 UNIX (FreeBSD in particular). I haven't fully researched either, just scrounged around the net looking for tutorials. On both all I've been able to come up with is nasm and a bunch of hello worlds that don't work. If someone could enlighten me to a website/good book on either of the two it would help me alot.
noarch / metal
IA32 == Intel x86. They're one and the same.
Anyways, maybe this (http://www.valhallalegends.com/files/386INTEL.TXT) reference might come in handy.
eew, ascii graphics :-)
The way I learned a lot was to write code in C, compile it with symbols, and use a debugger to see exactly what's happening.
Under unix it's pretty easy, if you know C.
Get nasm and make a file that looks like this:
; Hello, world!
extern puts
[SECTION .text] ;this is the section where the code goes
main: ; main() method in C
push dword ptr mystring ; push an argument to the function
call puts ; call the function
add esp, 4 ; clean the arguments off of the stack
[SECTION .data] ; this is where initialized data goes
mystring db "Hello, world!",0 ; remember the 0 at the end, C strings end with a null
[SECTION .bss] ; uninitialized data, instead of using d* size specifiers, use res*, but we don't need them in this program.
Save that as hello.asm. Now run nasm -f elf hello.asm. Then, link with libc, using gcc -o hello hello.o
Calling a C function is easy, PUSH the arguments in reverse order (dword ptr for strings!) and CALL the function, then add esp, [number of bytes you pushed].
How would you call a Java function from ASM?
j/k
Iczelion's Win32ASM site is a good reference. (http://win32asm.cjb.net) His tutorials are an excellent way to become familiar with the Windows API and calling it from an assembly language program. The (up/down)side to it is that his code is compiler specific (MASM) and uses its macros rather than pure assembly to demonstrate functions, so you'd be using some higher level syntax. Also, there are a good deal of links from there to other assembly sites.
If you do decide to go the way of Win32 stuff, this is a quick template I whipped up for MASM programs. It's by and large based off of the Iczelion stuff, so this will help with going through those. As is, it just creates an empty 300x200 window and processes the WM_DESTROY message.
;*****************
;** Always Here **
;*****************
.386
.model flat, stdcall
option casemap:none
;///////////////////////////////////////
;** End of essential compiler options **
;///////////////////////////////////////
;**************************************************************
;** Protocol declaration for entry-point of Windows programs **
;**************************************************************
WinMain proto :DWORD, :DWORD, :DWORD, :DWORD
;//////////////////////////////////////////////
;** End of pre-include protocol declarations **
;//////////////////////////////////////////////
;*******************
;** Include files **
;*******************
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
;//////////////////////////
;** End of include files **
;//////////////////////////
;*******************
;** Library files **
;*******************
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
;//////////////////////////
;** End of library files **
;//////////////////////////
;******************************************************
;** Protocol definitions dependent on included files **
;******************************************************
;//////////////////////////////////////
;** End of post-include declarations **
;//////////////////////////////////////
;*********************************
;** Constant Data Section (EQU) **
;*********************************
.const
;//////////////////////////////////
;** End of constant data section **
;//////////////////////////////////
;******************************
;** Initialized Data Section **
;******************************
.data
ClassName db "MyWindowClass",0 ;Window class name
AppName db "My Window Title",0 ;Window title
RegisterFailed db "Window Registration Failed!",0
CreateFailed db "Window Creation Failed!",0
;/////////////////////////////
;** End of initialized data **
;/////////////////////////////
;********************************
;** Uninitialized Data Section **
;********************************
.data?
hInstance HINSTANCE ? ;Handle to application instance
CommandLine LPSTR ? ;Pointer to command line string
;///////////////////////////////
;** End of uninitialized data **
;///////////////////////////////
;******************
;** Code Section **
;******************
.code
start:
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke GetCommandLine
mov CommandLine, eax
invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT
invoke ExitProcess, eax
WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
;Fill in members of the WNDCLASSEX structure
mov wc.cbSize, SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
push hInst
pop wc.hInstance
mov wc.hbrBackground, COLOR_WINDOW+1
mov wc.lpszMenuName, NULL
mov wc.lpszClassName, OFFSET ClassName
invoke LoadIcon, NULL, IDI_APPLICATION
mov wc.hIcon, eax
mov wc.hIconSm, eax
invoke LoadCursor, NULL, IDC_ARROW
mov wc.hCursor, eax
;Register the class
invoke RegisterClassEx, ADDR wc
test eax, eax
jz Class_Registration_Failed
;Create the window
invoke CreateWindowEx, WS_EX_CLIENTEDGE, ADDR ClassName, \
ADDR AppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, \
300, 200, NULL, NULL, hInst, NULL
test eax, eax
jz Window_Creation_Failed
mov hwnd, eax
;Show the window and update it.
invoke ShowWindow, hwnd, SW_SHOWNORMAL
invoke UpdateWindow, hwnd
;Message loop
.WHILE TRUE
invoke GetMessage, ADDR msg, NULL, 0, 0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov eax, msg.wParam
ret
Class_Registration_Failed:
invoke MessageBox, NULL, ADDR RegisterFailed, ADDR AppName, MB_OK
invoke ExitProcess, eax
Window_Creation_Failed:
invoke MessageBox, NULL, ADDR CreateFailed, ADDR AppName, MB_OK
invoke ExitProcess, eax
WinMain endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
;Process messages
.IF uMsg==WM_DESTROY
invoke PostQuitMessage, NULL
.ELSE
invoke DefWindowProc, hWnd, uMsg, wParam, lParam
ret
.ENDIF
xor eax, eax
ret
WndProc endp
end start
;//////////////
;** End code **
;//////////////
Why would you choose to write your program in some halfhighlevel language instead of either real assembler or real C? Note that you can use inline assembler to add whatever time critical code you want to a C program.
Because the comparisons are based on the instructions. Instead of .IF eax==0 it'd be test eax, eax: jz <label> The "halfhighlevel language" as you call it improves readability by reducing the number of comparisons and labels required. As long as you understand what it's really doing, I don't see why compiler macros like .IF are such a big deal.
QuoteBecause the comparisons are based on the instructions. Instead of .IF eax==0 it'd be test eax, eax: jz <label> The "halfhighlevel language" as you call it improves readability by reducing the number of comparisons and labels required. As long as you understand what it's really doing, I don't see why compiler macros like .IF are such a big deal.
The point is that you might as well use C for those types of things. If you find yourself using all of these macro constructs to hide assembler, why not just use a real high level language and save yourself the trouble?
QuoteThe point is that you might as well use C for those types of things. If you find yourself using all of these macro constructs to hide assembler, why not just use a real high level language and save yourself the trouble?
Because C.Ugliness >>>>> ASM.Ugliness? It's a matter of personal preference and aesthetics. Having hundreds of labels to handle every comparison is ridiculous, not to mention keeping track of them is a pain in the ass. So why not use the macro constructs? Using C would be fine if you wanted to program in C, but this is about assembly.
Grok it's not too hard, just link it with the jni library and push a few extra parameters to a JNI function.
...Grok: call a .NET method from x86 asm plz ;)
EDIT: ytop
QuoteBecause C.Ugliness >>>>> ASM.Ugliness? It's a matter of personal preference and aesthetics. Having hundreds of labels to handle every comparison is ridiculous, not to mention keeping track of them is a pain in the ass. So why not use the macro constructs? Using C would be fine if you wanted to program in C, but this is about assembly.
Sure, if you think asm looks better than C, and that's the reason you pick a language, go ahead. And let us all laugh at you while you're holding the programming language beauty competition ;)
Having lots of labels for comparisons is part of programming in assembly. Do the macros handle logical expressions too? (like .IF (a == 3 || a == 5) && b == 8 || b == 9 && a == 1)
I like programming in assembly, it's fun. To me though, the purpose of assembler has always been knowing exactly what instructions I am writing, and using that to write small and fast code. I don't see that happening when you're using macros for everything.
You're completely overexaggerating. There aren't macros in place for everything. More importantly, why do you care? It's still assembly, and if I like using macros, that's nice. If you don't, good for you. Also, I don't see how using a macro prevents small and fast code. A macro is exactly what it is--a bit of code that gets inserted each time you use it. Also, when you use a macro, you know exactly what instructions are going into it. It's not like having to include a runtime library, it's a whole 3-4 lines each time you use one. Seems to me you're just finding things to complain about.
I suppose if you know exactly what the macros do, and when they're not appropriate to use, you can go ahead and use them. I think there's a great risk that they will produce worse code than you would get if you let a C compiler do it for you though.
I also didn't see many explanations of the macros in that template for beginner assembler programmers you posted - they sure shouldn't be using a lot of macros they don't understand when they start programming. They'll probably also need to debug their programs and I'm not sure that will be made easier if they're running macros instead of instructions they actually wrote.
I've looked at the disassembly for the macros (inside of my programs) to see if it wouldn't be more efficient to write the routines, but it results in as efficient code as if I had done it manually.
asm is only good for inline code, since a C compiler can push out pages of asm in seconds, where a human cant. its less expensive to use up a LITTLE cpu time with slightly less efficient(only if ur an asm ninja) code than it is to use up precious human resources on trivial mind numbing tasks such as straight asm coding. That aside, asm does make a great place for excersize in programming.
Heres an easier way to do the hello world in a msgbox
.386
.Model Flat ,stdcall
Locals
Jumps
extern MessageBoxA:PROC
extern ExitProcess:PROC
mb_ok equ 0
hWnd equ 0
lptext equ offset text
lpcaption equ offset caption
.Data
text db "Hello World!",0ah
db "Magna Greets All Who did this!",0
caption db "What Up",0
.Code
Main:
push mb_ok
push offset caption
push offset text
push hWnd
call ExitProcess
End Main
shouldn't you be calling MessageBoxA() somewhere?
Quote from: iago on August 23, 2003, 07:21 PM
shouldn't you be calling MessageBoxA() somewhere?
Yes. His code absolutely does not work.
You need a
call MessageBoxA before that
call ExitProcess statement.
Quote from: Skywing on February 10, 2003, 04:25 PM
IA32 == Intel x86. They're one and the same.
Anyways, maybe this (http://www.valhallalegends.com/files/386INTEL.TXT) reference might come in handy.
I find it easier to view the 421 pages as a pdf.
http://www.microsym.com/386intel.pdf
Isn't that much harder to search in? Do you have some special tool to read it?
I personally Hate PDF's.. HATEHATEHATEHATEHATE them! My prof's at school use those, mostly because they're generally read-only, and they're SO annoying!
(Unless you're printing them off)
Also, somebody should find that topic on Free Assembly Books.. I still use Vol 2 a lot.
Quote from: Adron on August 31, 2003, 08:39 AM
Isn't that much harder to search in? Do you have some special tool to read it?
In Acrobat Reader you can use ctrl+f (find) to search just like any text file.
Yes, but that search feature is much slower, and the file itself redraws much slower, than the search feature in notepad or any other pure text editor/viewer.
I've uploaded the asm reference I use most often to my webspace, you can find it here:
http://www.ninjazone.net/asmhelp.zip
It's just basic instruction set reference, but it's very detailed on precisely how each instruction works, and VERY easy to search.
PDFs are indeed evil.
I wish there was some pdf-to-doc converter.. I know that Google.com has one built in, but it's not that great..
There are several PDF converters available. The one I use is pdf995. It sucks but it works. Basically you print from any app and pick "Print to PDF"
I want to go to .doc FROM .pdf, not the other way around.
Can go to html.
Quote from: iago on September 02, 2003, 12:06 PM
I wish there was some pdf-to-doc converter.. I know that Google.com has one built in, but it's not that great..
Have you tried doing print-to-file with Acrobat? I'm not sure how well that would work with the graphical portions, but it might capture the text parts right.