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 应用程序吗?

我再次知道这对这里的大多数人来说可能是显而易见的,但我真的很困惑!

PS 我之前在 Windows 上尝试过AndLinux,但安装量很大。

4

4 回答 4

7

Cygwin 是一个运行时层,它在 Windows 上提供来自 Unix/Linux 世界的库和软件。它不会让你的汇编代码运行,因为操作系统仍然是 Windows,所以所有的中断等仍然是 Windows,而不是 Linux 版本。此外,如果您真的想在 Windows 上运行汇编程序,您必须做的事情与在 Linux(或 DOS,就此而言)中做的事情有很大不同。

于 2009-02-18T14:37:47.853 回答
3

您可以完全在 Cygwin 中运行汇编程序。main我猜你的加载失败了,因为在 Windows 执行进程和你到达函数之间必须发生很多事情。当 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 调用约定记录在Internet 档案的此页面中;也许你能找到一个仍然有图像的类似的?

请注意,Cygwin 现在只能进行 32 位汇编;(非消费者)世界现在都是 64 位的,在现代处理器上的 64 位模式下,您有更多的寄存器和不同的调用约定。

于 2009-02-24T00:24:41.680 回答
1

真正做到这一点的最好方法是安装一个虚拟机(使用 VirtualBox 或类似的),并在其下安装完整的 Linux。听起来这可能太重而无法满足您的要求,但这是我目前唯一的建议。

于 2009-02-18T15:39:19.907 回答
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)
于 2017-03-23T17:16:12.227 回答