Author Topic: Creating my First Program  (Read 18195 times)

Offline WannaLearn

  • Jr. Member
  • *
  • Posts: 5
Creating my First Program
« on: November 07, 2016, 02:25:54 PM »
I've been lurking the forum for a few days filling myself up with notes trying to successfully create my first program in NASM, but with a few self imposed stipulations (until I'm ready to move forward). In creating this first program, however, I have a ton of questions.


The stipulations for now are that:
- I'm running Window 7 SP1
- I do not want to use DOSBox so Interrupts 0x21-24 are likely not applicable
- I do not want to rely on C so this is all NASM
- I would really like to avoid downloading Visual Studio or associated tools[the WDK] if I can (this depends on whether or not I NEED to interact with the Windows API -- related to Question 2 below)
- I've downloaded and installed MinGW
- I'm writing my code in Notepad++ and saving as *.asm
- I am linking using "ld" for now, but from what I've read, most seem to recommend "GoLink" (and Alink hasn't been updated in years?). I'll probably migrate to GoLink after I've assured myself that "ld" may be too limiting
- I want to know if printing is possible without the use of the Windows API or C because of the code below?


The only code that has worked for me in some capacity can be found here.
http://stackoverflow.com/questions/28733967/nasm-is-not-executing-file-in-windows-8
main.asm
Code: [Select]
[section] .text
    global _main

_main:
        mov eax, 6
        ret         ; returns eax (exits)
Linked:
Code: [Select]
c:\Users\James\Desktop>nasm -fwin32 main.asm
c:\Users\James\Desktop>ld -e _main main.obj -o main.exe
c:\Users\James\Desktop>main.exe
c:\Users\James\Desktop>echo %errorlevel%
6




My questions (a ton):
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.

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/

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. 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.
« Last Edit: November 07, 2016, 04:56:09 PM by WannaLearn »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Creating my First Program
« Reply #1 on: November 07, 2016, 07:20:01 PM »
Hi WannaLearn,

I am embarrassed as heck to not have an answer for you! The last time I ran Windows was Win98, and things have changed since then. I see you've posted your questions on Stack Overflow (great site, but who would call themself that?). I hope you can get better answers there (or here!), but let me see if I can help at all...

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.

I really hope some Windows users (I know we have some!) will jump in here and give you some better advice! Good Luck!

Best,
Frank


Offline soulvomit

  • Jr. Member
  • *
  • Posts: 31
Re: Creating my First Program
« Reply #2 on: November 08, 2016, 08:13:10 AM »
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.

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.

I realize this doesn't answer all your questions.

Thank you. (sorry for spelling errors, auto-correction/spell checking doesn't work at my workplace)

 
« Last Edit: November 08, 2016, 09:42:08 AM by soulvomit »

Offline soulvomit

  • Jr. Member
  • *
  • Posts: 31
Re: Creating my First Program
« Reply #3 on: November 08, 2016, 10:13:48 AM »
A bit more specific:

Quote
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?
Quote
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:
Code: [Select]
[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
 
Quote
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.
Quote
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
« Last Edit: November 08, 2016, 12:20:39 PM by soulvomit »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Creating my First Program
« Reply #4 on: November 08, 2016, 10:36:34 AM »
Quote
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


Offline soulvomit

  • Jr. Member
  • *
  • Posts: 31
Re: Creating my First Program
« Reply #5 on: November 08, 2016, 10:43:56 AM »
Code: [Select]
BLJdataTeknik@ARP-BLJDATA ~/Test
$ nasm64 -v
NASM version 2.12.03rc1 compiled on Oct  4 2016

BLJdataTeknik@ARP-BLJDATA ~/Test
$ nasm32 -v
NASM version 2.12.03rc1 compiled on Oct  4 2016

http://www.nasm.us/pub/nasm/releasebuilds/2.12.03rc1/win64/

http://www.nasm.us/pub/nasm/releasebuilds/2.12.03rc1/win32/

Offline soulvomit

  • Jr. Member
  • *
  • Posts: 31
Re: Creating my First Program
« Reply #6 on: November 08, 2016, 10:52:13 AM »
Quote
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.
« Last Edit: November 08, 2016, 11:21:38 AM by soulvomit »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Creating my First Program
« Reply #7 on: November 08, 2016, 11:53:37 AM »
Quote
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


Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Creating my First Program
« Reply #8 on: November 08, 2016, 12:25:50 PM »
Any help here, WannaLearn?
http://www.mingw.org/search/node/API

Best,
Frank


Offline soulvomit

  • Jr. Member
  • *
  • Posts: 31
Re: Creating my First Program
« Reply #9 on: November 08, 2016, 12:29:11 PM »
Quote
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...

Offline WannaLearn

  • Jr. Member
  • *
  • Posts: 5
Re: Creating my First Program
« Reply #10 on: November 08, 2016, 03:16:44 PM »
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.


Quote
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.


Quote
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:
Code: [Select]
[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.


 
Quote
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.
Quote
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.

Quote
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.


Quote
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-bit
According 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
« Last Edit: November 08, 2016, 03:23:11 PM by WannaLearn »

Offline soulvomit

  • Jr. Member
  • *
  • Posts: 31
Re: Creating my First Program
« Reply #11 on: November 08, 2016, 05:26:15 PM »
Quote
http://stackoverflow.com/questions/18296088/check-the-platform-of-the-installed-mingw-32bit-or-64-bit
According 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
Just wanted to get back to you with this one, I'll get back to the rest later on. Your version of MINGW is distinctly 32-bit. To do any 64-bit programming (-fwin64) in Nasm, you'll need the 64-bit version of MINGW (the one I linked earlier).

However, if you are as new as you stated, you should really do what the mingw getting_started tutorial tells you. Stick with 32-bit assembly (-fwin32). What you learn in the 32-bit space (we usually call it x86) will be easily translatable, when you do decide to take the jump over to 64-bit (called x86-64, or simply x64).     

EDIT: From a Windows developers standpoint MINGW and Cygwin offer a version of the GNU toolchain (includes programs like gdb - gnu debugger, ld - gnu linker and gcc - gnu compiler), which is normally only accessible to Linux users. Basically it ports the Linux GNU toolchain to Windows. Personally I need the whole GNU toolchain, but it is NOT needed to start Nasm programming.
If you want a lightweight development environment, without all the bells and whistles, you can simply get; Nasm for Windows, GoLink, Notepad++ and use the windows command prompt (cmd) to assemble and link.
« Last Edit: November 08, 2016, 07:31:36 PM by soulvomit »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Creating my First Program
« Reply #12 on: November 08, 2016, 05:51:42 PM »
Here's that example to assemble using "only Nasm". That is, it's assembled using Nasm's "-f bin" output mode, and stuffs the executable header onto it "by hand". I'm pretty sure it still works.

Code: [Select]
%define ONLY_NASM
%include "nagoa+.inc"

section .data

section .text

__start:

call MessageBox , NULL,"info","title",MB_OK
xor eax,eax
ret



    ; --- [ IMPORTS MUST BE THE LAST PART OF PROGRAM ]


LAST_BEGIN

__LIBS_         user32, "user32.dll"

__IMPORT_    user32,MessageBox, "MessageBoxA",0

LAST_END

This is 32-bit only. A 64-bit version should be possible, but this isn't the most flexible way to do it anyway. Let the linker do its job! If we can't figure out how to get the linker to do its job, this may be a way to get some output so you can start programming.

Best,
Frank


Offline soulvomit

  • Jr. Member
  • *
  • Posts: 31
Re: Creating my First Program
« Reply #13 on: November 08, 2016, 07:00:40 PM »
Quote
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.

If a windows console program crashes unexpectedly it stores the exit code in the EAX register. "echo %errorlevel%" basically just prints the EAX register to the screen. Since your program does nothing but store the value 6 in EAX, it prints 6. The %errorlevel% environmental variable will always contain the last value stored in EAX of a console program, unless the program crashes unexpectedly. In this case the %errorlevel% variable tells you something about the reason for the crash.

Basically what happens here is:
1. Your program says to CMD "The reason I exit is 6". (mov eax, 6)
2. Then exits. (ret - return out of _main)
3. Then you ask CMD "why did my program exit?". (echo %errorlevel%)
4. CMD naturally replies "6".

Hope that makes sense :)
« Last Edit: November 08, 2016, 07:26:35 PM by soulvomit »

Offline WannaLearn

  • Jr. Member
  • *
  • Posts: 5
Re: Creating my First Program
« Reply #14 on: November 09, 2016, 06:07:09 PM »
Please forgive the tardiness of my response. I was focused on the election last night.

Quote
http://stackoverflow.com/questions/18296088/check-the-platform-of-the-installed-mingw-32bit-or-64-bit
According 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
Just wanted to get back to you with this one, I'll get back to the rest later on. Your version of MINGW is distinctly 32-bit. To do any 64-bit programming (-fwin64) in Nasm, you'll need the 64-bit version of MINGW (the one I linked earlier).
However, if you are as new as you stated, you should really do what the mingw getting_started tutorial tells you. Stick with 32-bit assembly (-fwin32). What you learn in the 32-bit space (we usually call it x86) will be easily translatable, when you do decide to take the jump over to 64-bit (called x86-64, or simply x64).     
EDIT: From a Windows developers standpoint MINGW and Cygwin offer a version of the GNU toolchain (includes programs like gdb - gnu debugger, ld - gnu linker and gcc - gnu compiler), which is normally only accessible to Linux users. Basically it ports the Linux GNU toolchain to Windows. Personally I need the whole GNU toolchain, but it is NOT needed to start Nasm programming.
If you want a lightweight development environment, without all the bells and whistles, you can simply get; Nasm for Windows, GoLink, Notepad++ and use the windows command prompt (cmd) to assemble and link.
Wow, that's really interesting. How unfortunate that I'm using a 32-bit assembler, but I'll reread the directions and see what I can do.
In terms of this segment of your post, "If you want a lightweight development environment, without all the bells and whistles, you can simply get; Nasm for Windows, GoLink, Notepad++ and use the windows command prompt (cmd) to assemble and link", as far, as your experience with ld goes, would replacing GoLink with ld within those sets of tools be practical. I guess the answer is "not really" if I'm going to need to make API calls.


Here's that example to assemble using "only Nasm". That is, it's assembled using Nasm's "-f bin" output mode, and stuffs the executable header onto it "by hand". I'm pretty sure it still works.
Code: [Select]
%define ONLY_NASM
%include "nagoa+.inc"

section .data

section .text

__start:

call MessageBox , NULL,"info","title",MB_OK
xor eax,eax
ret



    ; --- [ IMPORTS MUST BE THE LAST PART OF PROGRAM ]


LAST_BEGIN

__LIBS_         user32, "user32.dll"

__IMPORT_    user32,MessageBox, "MessageBoxA",0

LAST_END
This is 32-bit only. A 64-bit version should be possible, but this isn't the most flexible way to do it anyway. Let the linker do its job! If we can't figure out how to get the linker to do its job, this may be a way to get some output so you can start programming.
Best,
Frank
This is absolutely great and I guess I've lucked out finding out from soulvomit taht i'm using a distinctly 32-bit version of nasm and am porting my code using ld's 32-bit linker. When I get everything in place I will definitely test the code.


Quote
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.

If a windows console program crashes unexpectedly it stores the exit code in the EAX register. "echo %errorlevel%" basically just prints the EAX register to the screen. Since your program does nothing but store the value 6 in EAX, it prints 6. The %errorlevel% environmental variable will always contain the last value stored in EAX of a console program, unless the program crashes unexpectedly. In this case the %errorlevel% variable tells you something about the reason for the crash.

Basically what happens here is:
1. Your program says to CMD "The reason I exit is 6". (mov eax, 6)
2. Then exits. (ret - return out of _main)
3. Then you ask CMD "why did my program exit?". (echo %errorlevel%)
4. CMD naturally replies "6".

Hope that makes sense :)
Unfortunately it makes perfect sense and also makes me cry. That's a real bummer. I'll be doing more reading as the day goes by. Thanks for everything, man. I really appreciate it.