编写汇编代码程序gdb

时间:2019-01-07 06:59:14

标签: c

我编写了一个简单的.c程序,并尝试通过使用gcc -S并将其运行为来进行转换:

但我不确定如何以这种格式编写程序,如果有人可以提出解决方案或帮助,将不胜感激。

1 个答案:

答案 0 :(得分:2)

/lib/ld-linux.so.2是32位动态链接器;这就是为什么外壳程序尝试execve()时会出现令人困惑的“没有这样的文件或目录”的原因。

使用以下命令之一来汇编+链接64位asm:

  • gcc -g -static -nostdlib start.s (无CRT或libc,静态可执行文件)。将其用于直接使用syscall且没有call到glibc函数的Hello World。
  • gcc -g -no-pie -nostartfiles start.s (没有CRT,但确实链接libc,从而创建了动态可执行文件。Linux上的动态链接器技巧使glibc init函数可以在执行之前运行到达您的_start入口点,因此您仍然可以call printf。与您制作链接libc的静态可执行文件不同。)
  • gcc -g -no-pie main.s (您写的是main而不是_start,就像C编译器会产生的一样)

如果要使用-o myprog以外的名称,请添加a.out选项。

要汇编+链接32位代码,请在其中任意一个中添加-m32

添加一个-v选项,以查看gcc前端在幕后使用的命令,如果您出于某些原因想要调用as和{{1} }。系统上的ld将知道libc和动态链接程序的正确路径。对于32位和64位代码,它们将有所不同。

gcc可以用来创建调试信息,以便在使用源代码视图而不是asm视图时更易于使用GDB。有关asm gdb提示,请参见the x86 tag wiki的底部。


也就是说,这在我的系统上有效,并且我认为动态链接程序路径对于现代x86-64 Linux系统是相当标准的。等效于-g

gcc -no-pie -nostartfiles start.s

如果您使用NASM或其他任何方法来创建as -o file.o file.s && ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o file -lc file.o ,请将其传递给gcc而不是asm源文件。 (例如.o)。有关更多详细信息,另请参见Assembling 32-bit binaries on a 64-bit system (GNU toolchain)


-no-pie allows 32-bit absolute addresses to work在64位模式下工作,因此像nasm -felf64 foo.asm && gcc -static -nostdlib foo.o -o foo(汇编为mov $message, %rsi而不是movq $sign_extended_imm32, %r64这样的代码)才能正常工作。 Difference between movq and movabsq in x86-64

movabsq $imm64, %r64还可以让您写-no-pie而不是call puts,否则像call puts@plt这样的内存间接调用将使用:gcc -fno-plt。链接器在call puts@GOTPCREL(%rip)中找到call puts时,将负责将call puts@plt重写为puts


您没有理由写-lc:使用mov $message, %rsi来利用静态地址位于虚拟地址空间的低32位中,或者使用mov $message, %esi来定位的独立代码,即使您的代码加载到低32位之外,也可以高效地工作。

如果您正在编译C,则希望使用lea message(%rip), %rsi,以便编译器代码源可以利用-fno-pie -no-piemov $message, %esi的优势。


此答案仅试图回答有关如何构建代码的问题,屏幕截图显示了该问题。要阅读编译器输出以了解其功能,请参阅How to remove "noise" from GCC/clang assembly output?

在这种特定情况下,mov array(,%rax,4), %ecxWhy does GCC use multiplication by a strange number in implementing integer division?

相关问题