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 exit
让call 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的主要内容,如果未能解决你的问题,请参考以下文章