5

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.

Community
  • 1
  • 1
handles
  • 7,639
  • 17
  • 63
  • 85
  • In case anyone stumbles upon this topic for the same reason I have, I have successfully compiled LLVM IR to run through Cygwin using the poster's commands. – sdasdadas Aug 11 '13 at 00:14

4 Answers4

7

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

Harper Shelby
  • 16,475
  • 2
  • 44
  • 51
  • thanks, that makes sense. Just one thing, what exactly is a "run time layer" ? Not being pedantic, genuinely don't know! – handles Feb 18 '09 at 14:41
  • bplus: cygwin basically interprets the C calls (as opposed to interrupts) of a program originally written for some sort of unix and then tries to call the appropriate Windows call instead. Since it catches C calls and not interrupts, you need to build against cygwin to be able to run it on cygwin. – Tamas Czinege Feb 18 '09 at 14:48
  • of course it's much more complicated and it does a lot of other stuff but that's the basic idea. – Tamas Czinege Feb 18 '09 at 14:49
  • DrJokepu: Certainly it is - but that would be an entirely different question (or a lot longer answer than I have time for now). – Harper Shelby Feb 18 '09 at 15:03
3

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
andrewdotn
  • 32,721
  • 10
  • 101
  • 130
  • It is a bug in the site; it works properly in the preview window. “AMD64 Architecture Programmer’s Manual” links to http://developer.amd.com/documentation/guides/Pages/default.aspx “this page” links to http://web.archive.org/web/20050208123742/http://ocliteracy.com/techtips/win32-callconv-asm.html I know ocliteracy.com/... is broken, that’s why I linked to the Wayback Machine – andrewdotn Jul 10 '09 at 01:26
  • Is `-mno-cygwin` necessary? It just makes sure we produce a MINGW executable right? – CMCDragonkai Oct 21 '16 at 14:07
  • The `The `-mno-cygwin` doesn't work on the latest GCC for Cygwin. – CMCDragonkai Oct 21 '16 at 14:18
1

The best way to do it really is to install a VM (using VirtualBox or somesuch) with a full install of Linux under it. It sounds like that may be too heavy to meet your requirements, but that's the only suggestion I have at the moment.

Brian Knoblauch
  • 20,639
  • 15
  • 57
  • 92
0

hi i had a similar problem but was able to figure it out using the -mconsole option in this cygwin session a file foo.c is first compiled and than run with the gdb debugger i hope that will help you

$ cat foo.c
int main( void )
{
        __asm__ ( "mov $5, %rax" );
        return 0;
}
$ make
gcc -ggdb -Wall -mconsole -o foo.o -c foo.c
gcc -ggdb -o foo foo.o -lm
$ gdb ./foo.exe
GNU gdb (GDB) (Cygwin 7.10.1-1) 7.10.1
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-pc-cygwin".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./foo.exe...done.
(gdb) l
1       int main( void )
2       {
3               __asm__ ( "mov $5, %rax" );
4               return 0;
5       }
(gdb) b 3
Breakpoint 1 at 0x1004010ed: file foo.c, line 3.
(gdb) r
Starting program: /cygdrive/c/C++/C/foo.exe
[New Thread 6724.0x13d0]
[New Thread 6724.0x1890]
[New Thread 6724.0x8e0]
[New Thread 6724.0xd84]

Breakpoint 1, main () at foo.c:3
3               __asm__ ( "mov $5, %rax" );
(gdb) info registers rax
rax            0x0      0
(gdb) s
4               return 0;
(gdb) info registers rax
rax            0x5      5
(gdb) c
Continuing.
[Thread 6724.0x1890 exited with code 0]
[Thread 6724.0x8e0 exited with code 0]
[Thread 6724.0xd84 exited with code 0]
[New Thread 6724.0x1368]
[Inferior 1 (process 6724) exited normally]
(gdb)
baz
  • 1,317
  • 15
  • 10