Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Linux汇编和printf_C_Assembly_Printf_Nasm - Fatal编程技术网

C Linux汇编和printf

C Linux汇编和printf,c,assembly,printf,nasm,C,Assembly,Printf,Nasm,我尝试用printf函数编写简单的汇编程序。我编译它nasm-f elf 64并使用gcc链接。运行后,我看到分段故障。怎么了 [Bits 32] extern printf global main section .data hello: db "Hello", 0xa, 0 section .text main: push hello call [printf] add esp, 4 mov eax, 1 mov ebx, 0 int 80h ia32上的Linux与a

我尝试用printf函数编写简单的汇编程序。我编译它
nasm-f elf 64
并使用
gcc
链接。运行后,我看到
分段故障
。怎么了

[Bits 32]

extern printf
global main

section .data 

hello:
db "Hello", 0xa, 0 

section .text

main:

push hello
call [printf]

add esp, 4

mov eax, 1
mov ebx, 0
int 80h

ia32上的Linux与amd64上的调用约定不同。由于您的代码使用前者,您必须将其组装为32位并与32位libc链接。在debian上,您需要libc6-dev-i386包

您还必须将“call[printf]”替换为“call printf”,这是一个错误

还要注意,在使用主界面时,应该从main返回,而不是执行exit系统调用以允许运行C运行时关闭代码

如果您正在使用amd64,则可能需要学习如何编写64位程序集


.

如果您真的希望获得代码头显示的32位二进制文件,则只需修复以下行:

call [printf]
将其更改为:

call printf

当您调用[printf]时,您调用的不是printf,而是第一个printf代码字节所指向的地址,该结构(
[address]
)被称为.

为什么要汇编一个明显是32位到
elf64
的程序?因为当我不这样做时,我看到:
/usr/bin/ld:i386输入文件的体系结构。/asemlebr.o与i386:x86-64输出不兼容
您在哪里编写了
printf
?如果您正在考虑调用C库中的一个,那么需要做的工作远不止这些-您需要确保调用库的初始化代码,根据您所在平台的ABI设置堆栈框架和参数,并将程序与库链接,至少…@twalberg:事实上这会很好用的。OP正在写入
main
,因此CRT启动代码将在调用main之前初始化glibc,即使在静态可执行文件中也是如此。在GLIMC动态链接的二进制中,也可以从<代码> >启动> /代码>安全,因为GLIBC的init函数是由动态链接器调用的,该机制使用在C++库代码中运行静态初始化器的相同机制。相关:了解更多关于静态与动态二进制文件以及是否链接libc的信息。这里的主要危险是
sys\u exit
不会刷新标准输出,但如果不是TTY,它将被完全缓冲。