我写了 x86-64 程序集。但它在 Windows 下不起作用,仅在 OnlineGDB (Linux) 下起作用
I wrote x86-64 Assembly. But it's not working under Windows, only on OnlineGDB (Linux)
我用汇编语言编写了一个 x86-64 代码。输出为 17.
.text
.LC0:
.string "%d\n"
printint:
pushq %rbp
movq %rsp, %rbp
subq , %rsp
movl %edi, -4(%rbp)
movl -4(%rbp), %eax
movl %eax, %esi
leaq .LC0(%rip), %rdi
movl [=12=], %eax
call printf@PLT
nop
leave
ret
.globl main
.type main, @function
main:
pushq %rbp
movq %rsp, %rbp
movq , %r8
movq , %r9
movq , %r10
imulq %r9, %r10
addq %r8, %r10
movq , %r8
movq , %r9
movq %r8,%rax
cqo
idivq %r9
movq %rax,%r8
subq %r10, %r8
movq %r10, %rdi
call printint
movl [=12=], %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.com/online_gcc_assembler 编译它时,我得到了正确答案 (17)。
我还在学习汇编语言。我搜索了答案,但找不到。你能解释一下这是什么原因吗?
关于我的笔记本电脑的详细信息
AMD RYZEN 5 Processor ( x64 Based )
64bit Windows 10
out.s:31: Error: 'cqo' is only supported in 64-bit mode
告诉您您尝试在 32 位模式下 assemble 这段 64 位代码。也许您尝试在 Windows 下使用 mingw32 而不是 64 位 mingw?
此代码适用于 x86-64 GNU/Linux:请注意在 RDI、RSI 中传递参数的调用约定以及 @plt
的使用。 DLL 不使用 PLT,那是 GNU/Linux 的事情(传统的动态链接,而不是新的样式 gcc -fno-plt
,早期绑定而不是惰性绑定)。这就是它在使用 x86-64 GNU/Linux.
的 OnlineGDB 中工作的原因
它不能在 64 位 Windows 下工作,除了在 WSL 中。甚至 Cygwin 64 也是源代码兼容层,而不是二进制/ABI/调用约定。
另外,它是用 AT&T 语法和 GAS 指令编写的。 NASM 使用带有不同指令的 Intel 语法;难怪当您尝试使用 nasm -fwin64
.
assemble 时,几乎每一行都是错误的
我用汇编语言编写了一个 x86-64 代码。输出为 17.
.text
.LC0:
.string "%d\n"
printint:
pushq %rbp
movq %rsp, %rbp
subq , %rsp
movl %edi, -4(%rbp)
movl -4(%rbp), %eax
movl %eax, %esi
leaq .LC0(%rip), %rdi
movl [=12=], %eax
call printf@PLT
nop
leave
ret
.globl main
.type main, @function
main:
pushq %rbp
movq %rsp, %rbp
movq , %r8
movq , %r9
movq , %r10
imulq %r9, %r10
addq %r8, %r10
movq , %r8
movq , %r9
movq %r8,%rax
cqo
idivq %r9
movq %rax,%r8
subq %r10, %r8
movq %r10, %rdi
call printint
movl [=12=], %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.com/online_gcc_assembler 编译它时,我得到了正确答案 (17)。
我还在学习汇编语言。我搜索了答案,但找不到。你能解释一下这是什么原因吗?
关于我的笔记本电脑的详细信息
AMD RYZEN 5 Processor ( x64 Based )
64bit Windows 10
out.s:31: Error: 'cqo' is only supported in 64-bit mode
告诉您您尝试在 32 位模式下 assemble 这段 64 位代码。也许您尝试在 Windows 下使用 mingw32 而不是 64 位 mingw?
此代码适用于 x86-64 GNU/Linux:请注意在 RDI、RSI 中传递参数的调用约定以及 @plt
的使用。 DLL 不使用 PLT,那是 GNU/Linux 的事情(传统的动态链接,而不是新的样式 gcc -fno-plt
,早期绑定而不是惰性绑定)。这就是它在使用 x86-64 GNU/Linux.
它不能在 64 位 Windows 下工作,除了在 WSL 中。甚至 Cygwin 64 也是源代码兼容层,而不是二进制/ABI/调用约定。
另外,它是用 AT&T 语法和 GAS 指令编写的。 NASM 使用带有不同指令的 Intel 语法;难怪当您尝试使用 nasm -fwin64
.