gpt4 book ai didi

c - C编译成汇编语言中的puts和printf有什么区别

转载 作者:太空狗 更新时间:2023-10-29 16:56:23 24 4
gpt4 key购买 nike

这是我使用 puts() 的 C 程序:

#include <stdio.h>
int main(void){
puts("testing");
}

使用gcc -S -o sample.s sample.c编译成Assembly后,得到的是:

        .file   "sample.c"
.section .rodata
.LC0:
.string "testing"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
movl $.LC0, (%esp)
call puts
leave
ret
.size main, .-main
.ident "GCC: (GNU) 4.4.5 20110214 (Red Hat 4.4.5-6)"
.section .note.GNU-stack,"",@progbits

我也是这样做的,这次我使用 printf() 而不是 puts,这就是我得到的结果:

    .file   "sample.c"
.section .rodata
.LC0:
.string "testing"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
movl $.LC0, %eax //this is the difference
movl %eax, (%esp)
call printf
leave
ret
.size main, .-main
.ident "GCC: (GNU) 4.4.5 20110214 (Red Hat 4.4.5-6)"
.section .note.GNU-stack,"",@progbits

这里是我不明白的地方,printf()函数mov $.LC0%eax,然后 mov %eax(%esp)puts() 函数 mov %.LC0 直接到 (%特别是)。我不知道为什么会这样。

最佳答案

在汇编级别,这两个函数的最大区别在于 puts() 函数只接受一个参数(指向要显示的字符串的指针)而 printf () 函数将采用一个参数(指向格式字符串的指针),然后是堆栈中任意数量的参数(printf() 是一个可变参数函数)。

请注意,绝对不会检查参数的数量,它仅取决于字符 % 在格式字符串中出现的次数。例如,这种特殊性被用于格式字符串格式错误利用方法,以交互方式探索进程堆栈的内容。

所以,基本上,区别在于 puts() 只有一个参数,而 printf() 是一个可变参数函数。

如果你想更好地理解这种差异,尝试编译:

#include <stdio.h>

int main(void) {
printf("testing %d", 10);
}

关于c - C编译成汇编语言中的puts和printf有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36960765/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com