我写了x86-64汇编。但是在Windows下不能工作,只有在OnlineGDB(Linux)上才能工作。

问题描述 投票:0回答:1

我用汇编语言写了一段x86-64代码。输出是17。

    .text
.LC0:
    .string "%d\n"
printint:
    pushq   %rbp
    movq    %rsp, %rbp
    subq    $16, %rsp
    movl    %edi, -4(%rbp)
    movl    -4(%rbp), %eax
    movl    %eax, %esi
    leaq    .LC0(%rip), %rdi
    movl    $0, %eax
    call    printf@PLT
    nop
    leave
    ret

    .globl  main
    .type   main, @function
main:
    pushq   %rbp
    movq    %rsp, %rbp
    movq    $2, %r8
    movq    $3, %r9
    movq    $5, %r10
    imulq   %r9, %r10
    addq    %r8, %r10
    movq    $8, %r8
    movq    $3, %r9
    movq    %r8,%rax
    cqo
    idivq   %r9
    movq    %rax,%r8
    subq    %r10, %r8
    movq    %r10, %rdi
    call    printint
    movl    $0, %eax
    popq    %rbp
    ret

当我用GCC编译时,我得到了这个错误。

out.s: Assembler messages:
out.s:5: Error: bad register name `%rbp'
out.s:6: Error: bad register name `%rsp'
out.s:7: Error: bad register name `%rsp'
out.s:8: Error: bad register name `%rbp)'
out.s:9: Error: bad register name `%rbp)'
out.s:11: Error: bad register name `%rip)'
out.s:19: Warning: .type pseudo-op used outside of .def/.endef: ignored.
out.s:19: Error: junk at end of line, first unrecognized character is `m'
out.s:21: Error: bad register name `%rbp'
out.s:22: Error: bad register name `%rsp'
out.s:23: Error: bad register name `%r8'
out.s:24: Error: bad register name `%r9'
out.s:25: Error: bad register name `%r10'
out.s:26: Error: bad register name `%r9'
out.s:27: Error: bad register name `%r8'
out.s:28: Error: bad register name `%r8'
out.s:29: Error: bad register name `%r9'
out.s:30: Error: bad register name `%r8'
out.s:31: Error: `cqo' is only supported in 64-bit mode
out.s:32: Error: bad register name `%r9'
out.s:33: Error: bad register name `%rax'
out.s:34: Error: bad register name `%r10'
out.s:35: Error: bad register name `%r10'
out.s:38: Error: bad register name `%rbp'

同样的,当我在NASM中编译时,我得到了以下错误。

out.s:1: warning: label alone on a line without a colon might be in error [-w+orphan-labels]
out.s:3: error: parser: instruction expected
out.s:5: error: parser: instruction expected
out.s:6: error: expression syntax error
out.s:7: error: parser: instruction expected
out.s:8: error: parser: instruction expected
out.s:9: error: parser: instruction expected
out.s:10: error: parser: instruction expected
out.s:11: error: parser: instruction expected
out.s:12: error: parser: instruction expected
out.s:18: error: parser: instruction expected
out.s:19: error: parser: instruction expected
out.s:21: error: label `pushq' inconsistently redefined
out.s:5: note: label `pushq' originally defined here
out.s:21: error: parser: instruction expected
out.s:22: error: expression syntax error
out.s:23: error: expression syntax error
out.s:24: error: expression syntax error
out.s:25: error: expression syntax error
out.s:26: error: parser: instruction expected
out.s:27: error: parser: instruction expected
out.s:28: error: expression syntax error
out.s:29: error: expression syntax error
out.s:30: error: expression syntax error
out.s:32: error: parser: instruction expected
out.s:33: error: expression syntax error
out.s:34: error: label `subq' inconsistently redefined
out.s:7: note: label `subq' originally defined here
out.s:34: error: parser: instruction expected
out.s:35: error: expression syntax error
out.s:37: error: label `movl' inconsistently redefined
out.s:8: note: label `movl' originally defined here
out.s:37: error: parser: instruction expected
out.s:38: error: parser: instruction expected

但是当我进入 https:/www.onlinegdb.comonline_gcc_assembler 并编译它,我得到了正确的答案(17)。

Screenshot

我还在学习汇编语言。我找过答案,但没有找到。你能解释一下这其中的原因吗?

关于我的笔记本电脑的详细信息

AMD RYZEN 5 处理器(基于x64的)。

64位Windows 10

assembly gcc compilation nasm
1个回答
1
投票

out.s:31: Error: 'cqo' is only supported in 64-bit mode 告诉你,你试图在32位模式下组装这段64位代码。 也许你试图在 Windows 下使用 mingw32,而不是 64 位 mingw?

这段代码适用于x86-64的GNULinux:请注意在RDI、RSI中传递args的调用惯例,以及使用的是 @plt. DLLs不使用PLT,那是GNULinux的事情(传统的动态链接,而不是新式的 gcc -fno-plt 与早期而不是懒惰绑定)。) 这就是为什么它能在OnlineGDB中工作,它使用x86-64 GNULinux。

除了在WSL里面,在64位Windows下是不行的。 即使Cygwin 64也是源码兼容层,而不是二进制ABI调用约定。


另外,它是用AT&T语法写的,有GAS指令。 NASM使用的是Intel语法,指令不同;难怪几乎每一行都是错误,当你试图用 nasm -fwin64.

© www.soinside.com 2019 - 2024. All rights reserved.