Cygwin:汇编语言开发?

5

首先,我不确定这是否应该成为我昨天在汇编和堆栈主题下的一部分,但我认为我在这里提出的问题是完全不同的。

我一直试图通过维基百科和谷歌来理解Cygwin究竟是什么,但我没有太多的运气。我刚开始使用gcc gas汇编器在Linux上进行汇编编程。我在工作时间只有Windows机器,所以我想在这里练习一些汇编语言编程,所以我想Cygwin可能会有所帮助。

错误地认为我在Linux中编写的代码可以使用Cygwin在Windows中编译和运行。Cygwin可以让我很好地编译代码:

as someAssmProg.as -o someAssmProg.o
ld someAssmProg.o -o someAssmProg

但如果我尝试在Cygwin下运行代码,

./someAssmProg

我看到了一个“未处理的win32异常”消息。

现在我猜想这是由于我的代码是为Linux编写的。我认为Cygwin应该能够解决这个问题。Cygwin只是用Unix命令行方式开发Windows应用程序吗?

不知道这对大多数人来说是否很明显,但我真的很困惑!

附言:我之前尝试过使用AndLinux在Windows上进行开发,但安装量相当大。


如果有人因为和我一样的原因偶然发现了这个主题,我已经成功地使用发布者的命令编译了LLVM IR以通过Cygwin运行。 - sdasdadas
4个回答

7

Cygwin是一个运行时层,它在Windows上提供了来自Unix/Linux世界的库和软件。它不允许您的汇编代码运行,因为操作系统仍然是Windows,所以所有的中断等仍然是Windows版本,而不是Linux版本。此外,如果您真的想在Windows上运行汇编语言,您必须采取与Linux(或DOS)完全不同的方法。


谢谢,那很有道理。只有一件事,什么是“运行时层”?我并不是故意挑剔,真的不知道! - handles
bplus: Cygwin基本上是解释某种Unix系统下编写的程序的C调用(而不是中断),然后尝试调用相应的Windows调用。由于它捕获的是C调用而不是中断,因此您需要针对Cygwin进行构建才能在Cygwin上运行它。 - Tamas Czinege
当然,这个问题要复杂得多,并且它还会做很多其他的事情,但这就是基本思路。 - Tamas Czinege
DrJokepu:当然可以,但那将是一个完全不同的问题(或者比我现在有时间回答的更长)。 - Harper Shelby

3
你可以在Cygwin中完全运行汇编程序。我猜测你的加载失败是因为当Windows执行进程时,必须发生大量的事情,才能到达main函数。当gcc给出汇编语言作为输入时,它将链接适当的样板代码以生成有效的可执行文件。
以下是一个示例汇编程序。将其保存为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"

然后用以下命令运行:

$ gcc -mno-cygwin hello.s -o hello && ./hello
Hello, world.
11

您处理器的汇编指令的参考资料包含在AMD64 Architecture Programmer’s Manual中。C调用约定记录在这个页面中,也许您可以找到一个还有图片的类似页面?
请注意,目前Cygwin只能进行32位汇编;现在(非消费者)世界都是64位的,在现代处理器上的64位模式下,您有更多的寄存器和不同的调用约定。

这是网站上的一个错误;在预览窗口中它正常工作。“AMD64架构程序员手册”链接到http://developer.amd.com/documentation/guides/Pages/default.aspx“此页面”链接到http://web.archive.org/web/20050208123742/http://ocliteracy.com/techtips/win32-callconv-asm.html我知道ocliteracy.com/...已经失效了,这就是为什么我链接到Wayback Machine的原因。 - andrewdotn
“-mno-cygwin” 是必要的吗?它只是确保我们生成一个 MINGW 可执行文件,对吗? - CMCDragonkai
-mno-cygwin 在最新的 Cygwin GCC 上不起作用。 - CMCDragonkai

1

实际上,最好的方法是安装一个虚拟机(使用VirtualBox或类似软件),在其中完整安装Linux。听起来这可能太重了,不符合您的要求,但目前这是我唯一的建议。


这也是我得出的结论。 - Chris Snow

0

嗨,我曾经遇到过类似的问题,但是通过在这个Cygwin会话中使用-mconsole选项,我成功地解决了它。首先编译一个名为foo.c的文件,然后使用gdb调试器运行它。希望这能帮到你。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接