Firstly I'm not sure if this should be part of the thread I started yesterday on assembly and the stack but I think the question I'm asking here is quite different.
I'm been trying to understand what exactly Cygwin is, via Wikipedia and Google, I'm not having much luck. I've just begun assembly programming on Linux using the gcc gas assembler. I'm using a machine at work during lunch that only has Windows on it. I wanted to practice some assembly language programming here so I thought Cygwin might be able to help.
Mistakenly I believed that the code I was writing in Linux could just be compiled and run in Windows using Cygwin. Cygwin allows me to compile the code fine:
as someAssmProg.as -o someAssmProg.o
ld someAssmProg.o -o someAssmProg
But if I try to run the code under Cygwin,
./someAssmProg
I get a "unhandled win32 exception occured" message
Now I am assuming this is because the code I'm writing is intended for Linux. I thought though that Cygwin would deal with this. Is Cygwin just really meant to be used to develop Windows applications in a Unix style command line way?
Again I know this is probably obvious to most folks here but I'm genuinely confused!
P.S I've tried AndLinux before for Windows, but it's quite a hefty install.
Cygwin is a runtime layer that provides libraries and software from the Unix/Linux world on Windows. It will not allow your assembler code to run, as the OS is still Windows underneath, so all the interrupts, etc. are still the Windows, not Linux, versions. In addition, if you really want to run assembler on Windows, you have to do things a lot differently than you do in Linux (or DOS, for that matter).
You can totally run assembly programs in Cygwin. I’m guessing that your load failed because there’s a bunch of stuff that has to happen between when Windows executes a process and when you get to the main
function. When gcc is given assembly as input, it will link in the appropriate boilerplate code to generate a valid executable.
Here’s a sample assembly program. Save it as hello.s:
.intel_syntax noprefix
.section .text
.globl _main
_main:
enter 0, 0
// welcome message
push OFFSET s_HelloWorld
call _printf
pop eax
// add three numbers
push 2
push 4
push 5
call _addThree
add esp, 3 * 4
// print returned value
push eax
push OFFSET s_PercentD
call _printf
add esp, 2 * 4
xor eax, eax
leave
ret
// Add three numbers
_addThree:
enter 0, 0
mov eax, DWORD PTR [ebp + 8]
add eax, DWORD PTR [ebp + 12]
add eax, DWORD PTR [ebp + 16]
leave
ret
.section .rdata
s_HelloWorld:
.ascii "Hello, world.\n\0"
s_PercentD:
.asciz "%d\n"
then run it with
$ gcc -mno-cygwin hello.s -o hello && ./hello
Hello, world.
11
The reference for your processor’s assembly instructions are contained in the AMD64 Architecture Programmer’s Manual. The C calling convention is documented in this page from the Internet Archive; maybe you can find a similar one that still has the images?
Note that Cygwin will only do 32-bit assembly right now; the (non-consumer) world is all 64 bits now, and in 64-bit mode on modern processors you have many more registers and different calling conventions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With