关闭

汇编解决的第一个小问题

165人阅读 评论(0) 收藏 举报
一朝掌握汇编语言,终生理解计算机系统。

--题记

现在计算机发展及其迅速,我们能学可学的东西很多,汇编语言已经不再像以前那样必要,但是底层的东西变化却很慢,学习以下我觉得是不吃亏的,尤其是以后立志走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
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	subq	$16, %rsp
	leaq	-1(%rbp), %rax
	movq	%rax, %rsi
	movl	$.LC0, %edi
	movl	$0, %eax
	call	__isoc99_scanf
	leaq	-4(%rbp), %rax
	movq	%rax, %rsi
	movl	$.LC1, %edi
	movl	$0, %eax
	call	__isoc99_scanf
	movzwl	-4(%rbp), %eax
	movswl	%ax, %edx
	movzbl	-1(%rbp), %eax
	movsbl	%al, %eax
	movl	%eax, %esi
	movl	$.LC2, %edi
	movl	$0, %eax
	call	printf
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:67532次
    • 积分:3053
    • 等级:
    • 排名:第11370名
    • 原创:244篇
    • 转载:6篇
    • 译文:0篇
    • 评论:13条
    最新评论