x86-64 在线汇编,带有诸如 https://www.mycompiler.io/new/asm-x86_64 之类的 IDE

Posted

技术标签:

【中文标题】x86-64 在线汇编,带有诸如 https://www.mycompiler.io/new/asm-x86_64 之类的 IDE【英文标题】:x86-64 assembly online, with an IDE such as https://www.mycompiler.io/new/asm-x86_64 【发布时间】:2021-02-01 13:22:00 【问题描述】:

谁能帮我写下与下面的程序等效的程序,以便它在https://www.mycompiler.io/new/asm-x86_64 的在线 IDE 上运行?我是一名老师,想向我的学生展示如此真实的工作组装,这样他们就不再认为 Little Man Computer 是真实的。我只是现在没有时间自己解决!

section .text
    global main
    extern printf           ; the C function to be called
main:
 
    mov eax, 45
    mov ebx, 55
    add eax,ebx
    push eax
    push message
    call printf
    add esp, 8
    ret
 
message db "Value = %d", 10, 0

【问题讨论】:

根据 ABI 的某些参数,甚至对于可变参数函数(如 printf),可能会使用寄存器传递 这不会像在线工具不允许您在 libc 中链接那样简单。也许选择了一个不同的呢?例如。你可以试试gcc.godbolt.org。 很高兴使用godbolt。我没有看到在那个上实际运行汇编代码的方法。 这能回答你的问题吗? How to print a number in assembly NASM? @Tortoise 选择程序集作为源文件格式。请注意,这是 GNU 程序集,而不是 NASM 程序集。 【参考方案1】:

https://www.mycompiler.io/new/asm-x86_64 显然没有为 asm 链接 libc,因此您可以直接使用 Linux 系统调用(通过 syscall),而不是像 printf 这样的 libc 函数。

https://www.onlinegdb.com/ 有 asm,但只有 GCC (GAS),没有 NASM。不过,您仍然可以使用.intel_syntax noprefix 来获得 GAS 的类似 MASM 的 Intel 语法。 至关重要的是,它确实有一个有效的 GDB 设置,可让您单步执行 asm 并查看寄存器值。这对于学习 asm 几乎是必不可少的:多种错误会导致完全相同的错误(段错误、或没有输出),这些是汇编程序无法诊断的错误。在没有调试器的情况下学习 asm 就像在蒙着眼睛(或其他丰富多彩的类比)时尝试构建机器人。

准确了解每条指令的作用是完全您应该如何看待 asm,尤其是在尝试理解为什么您的程序没有按照您希望的那样运行时。


如果您确实想在没有 libc 的情况下使用特定的 IDE (mycompiler.io),How do I print an integer in Assembly Level Programming without printf from the c library? 的代码可以将无符号整数转换为十进制 ASCII 字符串并将其提供给 x86-64 Linux write 系统调用与rax=1 / syscall

extern exitcall exit 组装但不链接,作为快速测试:undefined reference to 'exit'

还有https://tio.run/,它有 NASM 和 FASM 以及 GAS。 FASM 允许通过让 FASM 直接生成可执行文件 (format ELF executable 3) 而不是 TIO.run 希望能够链接到 64 位可执行文件的 .o 来生成 32 位代码。我用它来测试一些代码高尔夫答案 (like this),我特别想要 32 位模式,而不是 64 位,所以我可以在指针上使用 dec edi 而不需要 REX 前缀。


我注意到您使用 32 位堆栈参数调用约定来尝试调用 printf。这不是 x86-64 System V ABI 的工作方式 (What are the calling conventions for UNIX & Linux system calls (and user-space functions) on i386 and x86-64),所以请下定决心是否要教授 32 位代码(它的调用约定更简单但更差,几乎所有东西都可以是 32 位的) ,或 x86-64,其中普通代码通常利用 32 位操作数大小和隐式零扩展为 64 位。并且 args 在寄存器中传递给系统调用,调用约定与函数调用类似。

相关:32 位 Hello, world in assembly language with Linux system calls? 与 int 0x80 系统调用和大量解释。

另外,您不想在 64 位代码中使用 int 0x80:What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?

【讨论】:

以上是关于x86-64 在线汇编,带有诸如 https://www.mycompiler.io/new/asm-x86_64 之类的 IDE的主要内容,如果未能解决你的问题,请参考以下文章

减法和检测下溢,最有效的方法? (带有 GCC 的 x86/64)

x86_64 ABI:反汇编问题

汇编语言-X86处理器架构-64位x86处理器

如何在 x86-64 汇编中使用堆栈?

X86-64 汇编学习1

X86-64 汇编学习1