汇编解决的第一个小问题

一朝掌握汇编语言,终生理解计算机系统。

--题记

现在计算机发展及其迅速,我们能学可学的东西很多,汇编语言已经不再像以前那样必要,但是底层的东西变化却很慢,学习以下我觉得是不吃亏的,尤其是以后立志走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  的内容被改变了。  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值