Let me open by saying, Wow! I was not expecting this much help, but you guys are amazing! I was trying to pear down each of your posts to respond selectively to the portions I found mot important, but literally every answer you guys gave provided me with such useful information that I have to apologize because my subsequent reply will be pretty long. I LOVE THIS because it's actually helping me learn!
You should not need VS. In fact, it can be done with only Nasm! There's a set of macros called "nagoa+" which I was slightly involved with, long ago, which I think still works. This is not the way I would prefer to do it. I would prefer to let the linker do its job. But... if all else fails...
http://home.myfairpoint.net/fbkotler/nagoa20120202.zip
I think I have one simple example for this, which I will post if you want it.
I think - but I'm not sure - that the reason GoLink is preferred is that it doesn't need a library. I think you can just list the dll's you need on the command line and GoLink will find the APIs. (you do need to use the APIs!)
Alink is, as you know, obsolete... but it does include a library. I ASSume ld has a library, too, but I don't know where to find it. As I recall, I stole the library from Hutch's "masm32" and managed to link against it using ld from the Cygwin package. I don't remember details. You really "should" be able to use ld (MinGW exists for a reason!), but try GoLink if you need to.
You've done well to even get an "errorlevel" out of this. While you've proved that "ret" works, you really should use "ExitProcess" (_Exitprocess@4 perhaps). I'd look for an example using "MessageBoxA" to start with, them go on to "GetStdHandle" and "WriteFile" and/or some "Console..." API's. You should be ablle to find the APIs and their documentation around MicroSoft somewhere.
Thanks for alerting me to Nagoa+. So far I've downloaded it and placed it into my Google drive, did some minimal reading on it, and think that I'm seeing that it is kind of a macro suite that eases the burden of making API calls because it has them assorted/stored for you(?) and is involved with the Win32n.inc file. [No need to respond to this]Interestingly, in a folder I compiled full of linkers along with MINGW I found that Win32n.inc was included (probably came with MINGW), but I'm surprised I hadn't noticed that before. No need to respond to this; I just found it interesting.
Please, by all means, do post the example involving Nagoa+. Pending mistakes I'll likely make, any pre-guidance would be deeply appreciated.
Yea, a Google group and the Golink Dev page suggested that it would find the API calls, but that to me seems highly suspect because, from what I've read, the API calls change and also vary by OS+Service pack. It makes me wonder if you need to be using GoASM which I believe has its own syntax and is kind of like NASM "modified," if you will, or if I should really follow this quote to the letter: "In a major step forward, GoLink does not need LIB (library) files. Instead GoLink looks inside the exporting executables themselves to find the imported functions and data. This makes GoLink much easier to use than other linkers and also speeds up the linking process." Not sure what to make of that just yet.
I see that soulvomit mentioned Cygwin as well. I'll read into it more as I go forward.
Notepad++ and cygwin64 (ld and nasm) is absolutly all you need on windows. I do all my work with only these tools. With these tools you can assemble/compile all windows pe executables such as .exe's and .dll's.
I wonder, does that mean download of MINGW was unneccessary? Does it come with a bulk of extra packages which is what would make Cygwin64 a better alternative?
You'll need to use the windows API for anything that is "interacting" with the OS. The big ones are; I/O operations (Console read/write, Window interactions - Buttons, Textfields), Threading - since it is an OS kernel feature (CreateTread(), CreatRemoteThread()) and Dynamic allocation - also an OS kernel feature (HeapAlloc(), VitualAlloc(), VirtualFree()). Most other things you can do in "pure" ASM, which makes your code portable to other x86-64 systems.
It sounds to me like what you really want to be looking into, is OS development. Start by making a simple bootloader and evolve it with features. There is a lot to learn here, but they have some great tutorials over at osdev.org. The problem with os development is testing and debugging. You will want a virtual machine to run your os/bootloader, and then you will need a remote debugger to debug the VM running your os/bootloader. Once you have a basic os up and running you'll have an "blank slate" enviroment, where you can do anything you want. You have direct control over the CPU security functions and the memory model.
If you are only comfortable with user-mode development, you will have to either "get creative" or use the system calls of your OS. As an example you can "get creative" by using the stack to do dynamic allocation, this way you don't have to use the VirtualAlloc(), VirtualFree() API functions. Also get yourself a good user mode binary debugger. I prefer x64dbg. But you can use anything, as long as it supports x32-64 instructions.
Yep. You've hit the nail on the head. Whether or not I'll get as far as really getting into the weeds of OSDevelopment only time will tell if I can finally manage my drearily hectic schedule. I'm going to have to do a lot more reading on the subject of User, Kernel, etc. modes because at this point I don't fully understanding them but I've seem them come up in certain tutorials, but my focus for now is getting something to run then experimenting with everything else as I gain more experience.
1. The fact that in the code above "ret" by itself gives output, although it just returns whatever is in EAX, is there a way to use it (or another directive outside of the Windows API) to return the contents of a variable (hopefully a string variable)? I tried to use ret with DOS calls, but as noted above, that definitely doesn't work for obvious reasons.
Not quite sure what you are asking here. When you "ret" from your main function the program ends, surely?
I'm really an absolute beginner so I might not be presenting things as they are and I apologize for that. What I'm saying here is that if I change the value being entered in EAX in _main to pretty much anything and use the "ret" directive at the end, when I run the link command in CMD and print the errorlevel I get whatever was in EAX. When "ret" is not included I receive an error when I run the produced executable and when EAX is
excluded I receive what I presume is a memory address from the Errorlevel.
2. In case I absolutely must use the Windows API, do I have to download the WDK tools or is there possibly another library or piece of software I can download and install to interact with it? The last time I installed Visual Studio and associated WDK tools they took up a ton of memory and massively slowed down my computer. If I can interact with the API without the WDK tools, or can actually print output without having to interact with the API that would be far more preferable. The unfortunate thing is that at current, every time I use code with the extern commands "ld" tells me that the references to the commands are undefined. In the same vein is there a table I can consult containing accurate calls to the API (i.e. _ExitProcess@4 vs. ExitProcess). I found this link to what think may be the NT API but I'm not sure it applies given my stipulations, but in reality, I'm just kind of confused:
http://j00ru.vexillium.org/ntapi/
The important part of the Win API is contained in the kernel32 and user32 dlls. They are both wrappers for the ntdll. Technically you dont need anything other then these files.
I don't know how to link against Win API with ld (if you find a way please share! ). Everytime I need to link against the Win API (which is almost never), I use GoLink. Something like this will work:
[section] .text
extern ExitProcess
global _main
_main:
mov eax, 6
push 0 ;arg of ExitProcess: _In_ UINT uExitCode
call ExitProcess
ret ;returns eax (exits)
nasm -f win32 main.asm
golink /console /entry _main main.obj kernel32.dll user32.dll
This is my personal favorite QOTD! I haven't run it yet, but just reading it due mainly to the example, I can tell it will be a MASSIVE help! Can't thank you enough.
3. In bits of code I've encountered I've seen directives for [Bit 16], [Bit 32], and [Bit 64]. [Bit 16] is likely ignorable, but I'm confused by the [Bit 32] and [Bit 64] for the following reasons which may not even be related: Via the code above I'm using the command, "nasm -fwin32 main.asm", then I'm linking it successfully and going on to receive output.
Don't worry to much about this. The bit directives are there to tell the assembler which instructions/register usage are valid.
For some reason, though I have not read the full "ld" documentation yet, when I use the command "nasm -fwin64 main.asm" and link it in the same way I receive an error saying "main.obj: File not recognized: File format not recognized". I don't understand why differentiating between 32 and 64 while I'm on a native 64-bit machine causes an error although this probably is just unique to ld.
I've tried assembling and linking your program and it assembles and links just fine:
nasm32 -fwin64 main.asm
nasm64 -fwin64 main.asm
ld -e _main main.obj -o test.exe
Maybe try updating your nasm?
EDIT: I believe that the problem is you are using a 32-bit version of the GNU toolchain. Try switching to cygwin64 or mingw64. Here are the links:
Mingw64 - https://sourceforge.net/projects/mingw-w64/
Cygwin64 - https://cygwin.com/install.html
Intersting! When I initially read your examples I saw "nasm32" vs. "nasm64" and had a hunch that what was going on was that my nasm instance produced 32-bit grounded files and did not properly create those meant for 64 bit systems. The weird thing about that is that I would have expcted an error when switching the -fwin32 to fwin64. I will read into and download MINGW64 and Cygwin64 as the day goes on.
This happens because you are using the 32-bit version of nasm, switch to the 64-bit version and it assembles just fine (I've tested it)
Well... tested is tested, but this is a new one on me. What does "nasm -v" produce for the "64-bit version"?
Best,
Frank
But because you asked I tried;
nasm32 -f win64 main.asm
and it works fine as well So I stand corrected.
EDIT: I got it confused. It was linking, which produced the error for the OP. I thought it was during assembly. So I guess the problem could be that he is using the 32-bit GNU toolchain, to link a 64-bit object file? I cannot test this, because I only have cygwin64 installed.
Alright. I'll test when I get a moment later in the day. Thanks so much for the help both of you especially on this bit of confusion.
and it works fine as well
That's what I would have expected. Thanks!
With the Linux ld, the 32-bit version produces 32-bit code from "-f elf32", of course. The 64-bit ld produces 64-bit code from "-f elf64" by default, but can be told "-m elf_i386" to get 32-bit code out of it.
WannaLearn is apparently getting "some" output out of "-f win32" and whatever ld.exe he's got. I suspect he'd like to get "hello world" out if it (perhaps a MessageBox). Worry about getting both 32- and 64- bit out of it after getting either...
I don't think, if you're using GoLink, you need to tell GoLink whether it's 32- or 64-bit code - I think that information is in the .obj header. I could be wrong on that, and I don't know how to get 64-bit code out of ld - even just "push 6 / ret".
Best,
Frank
Until he gets back to us we can only guess. He specifies that he is using mingw, but not which version. He'll need this version to have any joy with 64-bit programming https://sourceforge.net/projects/mingw-w64/
GoLink is deffo the more "just starting out" friendly option...
http://stackoverflow.com/questions/18296088/check-the-platform-of-the-installed-mingw-32bit-or-64-bitAccording to this thread which says that you check the MINGW version by using the "gcc --version" command, The MINGW version I'm using is:
gcc (rubenv-4.7.2-release)
I just wanted to note that I download MINGW 2 days ago and followed the direction in the Guide linked below which reads: "Click on this mingw-get-setup.exe link, to download the latest available version of mingw-get-setup.exe"
http://www.mingw.org/wiki/getting_started