汇编解决的第一个小问题

来源:互联网 发布:电脑故障修复软件 编辑:程序博客网 时间:2024/05/22 20:28
一朝掌握汇编语言,终生理解计算机系统。--题记现在计算机发展及其迅速,我们能学可学的东西很多,汇编语言已经不再像以前那样必要,但是底层的东西变化却很慢,学习以下我觉得是不吃亏的,尤其是以后立志走C/C++ 路线的程序员。一句话:我学的就是情怀!昨天学妹问我一个问题,很简单。是这样的。
#include<stdio.h>int main(){    char a;    short b;    scanf("%c",&a);    scanf("%d",&b);    printf("%c %d \n",a,b);}
为什么这里的a 变量不能打印。现在我们逐层分析:相信C语法不错的同学都能看到%d 和 short 不对等,语法不对,确实是这样。可是为什么这样?这就需要了解变参函数知识了,变参函数中参数不对等,对很靠近答案了。但是明明是b错了,但是为什么是a有问题?我们看看汇编代码:
.file"tt.c".section.rodata.LC0:.string"%c".LC1:.string"%hd".LC2:.string"%c %d \n".text.globlmain.typemain, @functionmain:.LFB0:.cfi_startprocpushq%rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq%rsp, %rbp.cfi_def_cfa_register 6subq$16, %rspleaq-1(%rbp), %raxmovq%rax, %rsimovl$.LC0, %edimovl$0, %eaxcall__isoc99_scanfleaq-4(%rbp), %raxmovq%rax, %rsimovl$.LC1, %edimovl$0, %eaxcall__isoc99_scanfmovzwl-4(%rbp), %eaxmovswl%ax, %edxmovzbl-1(%rbp), %eaxmovsbl%al, %eaxmovl%eax, %esimovl$.LC2, %edimovl$0, %eaxcallprintfleave.cfi_def_cfa 7, 8ret.cfi_endproc.LFE0:.sizemain, .-main.ident"GCC: (GNU) 4.9.2 20150212 (Red Hat 4.9.2-6)".section.note.GNU-stack,"",@progbits
我们可以看到,edi 寄存器保存的是变参。当我们使用"%d"接收参数的时候,想当于直接给存放b的寄存器强制放了4字节内容,我们知道程序在运行时是以栈的形式存储变量的,所以4字节的b强行符覆盖到了a.所以变量a  的内容被改变了。 

查看原文:http://zmrlinux.com/2016/05/30/%e6%b1%87%e7%bc%96%e8%a7%a3%e5%86%b3%e7%9a%84%e7%ac%ac%e4%b8%80%e4%b8%aa%e5%b0%8f%e9%97%ae%e9%a2%98/
0 0
原创粉丝点击