新书推荐:2.1 显示计算结果

本节必须掌握的知识点:

示例二源代码

代码分析

汇编解析     

2.1.1 示例二

计算整数和并显示

示例二计算整数和并显示结果。鼠标选中VS左侧解决方案资源管理器“源文件”,点击鼠标右键,选择“添加”>“新建项(W)…”,新建项目2-1-1.c。编辑源代码如下所示:

代码示例2

/*

显示整数11和22的和

*/

#include <stdio.h>//C标准库输入输出头文件

int main(void)//函数头

{

 printf("%d", 11 + 22);  //%d用十进制数显示整数11+22的和

  return 0;//结束返回

}

●输出结果:33

2.1.2 代码分析

●注释

多行注释:/* ……*/ 之间的部分称为注释。

单行注释://。

printf ("%d",11+22); //格式化说明符%d用于十进制数显示整数11+22的和。

●printf函数:格式化输出函数。

printf函数可以在显示器控制台窗口进行输出操作,打印format格式化字符串。

printf函数的第一个实参“%d”为format格式化常量字符串,指定了输出格式为十进制数格式 。第二个实参为一个整数算术表达式“11+22”,由编译器计算出结果,并替换第一个参数中的“%d”。

printf函数为可变参数函数,参数的个数不确定,参数的个数根据实际需要确定。参数的个数等于格式化说明符的个数加上format格式化常量字符串。包含两个以上参数时用逗号分隔。

提示

1.C语言语句以分号结尾。

2.{…}之间的语句按顺序执行。

2.1.3 汇编解析

汇编代码(makefile文件略)

;C标准库头文件和导入库

include vcIO.inc

.data

szMsg db "%d",0

.code

start:

invoke printf,offset szMsg,11+22  ;控制台窗口输出整数和

invoke _getch  ;等待输入单个字符

ret ;结束返回

end start

上述代码为2-1-1.c的汇编代码实现。vcIO.inc头文件在示例一中已经详细讲述,此处不再赘述。

.data数据段定义了格式化常量字符串szMsg。

.code代码段语句:invoke printf,offset szMsg,11+22;控制台窗口输出整数和

调用printf函数按照十进制整数格式输出11+22的整数和。该语句为高级汇编写法,等价于下面的汇编语句:

mov eax,11 ;eax累加器

add eax,22 ;加法运算

push eax ;累加和入栈

push offset szMsg ;格式化常量字符串偏移地址入栈

call printf ;调用printf函数输出结果

上述代码先计算11+22的和,保存在累加器eax中,然后压入堆栈传参,接着将格式化常量字符串的偏移地址入栈,最后call指令调用printf函数。

反汇编代码

VS中在printf一行按F9下断点,然后按F5调试执行,反汇编窗口的反汇编代码如下:

printf("%d", 11 + 22); //%d用十进制数显示整数11+22的和

01141838 push 21h ;十六进制数21h等于十进制数33

0114183A push offset string "%d" (01147B30h) ;将格式化字符串地址压入堆栈

0114183F call _printf (0114104Bh) ;调用printf函数

01141844 add esp,8 ;恢复堆栈平衡

上述反汇编代码中,第一个push语句将加法表达式11+22的和入栈,和由编译器在编译时计算出结果。第二个push语句将格式化字符串偏移地址(01147B30h)入栈。call指令调用C语言标准库函数printf输出结果。最后一条语句add esp,8恢复堆栈平衡。

结论

1.一条C语句printf("%d", 11 + 22);对应多条汇编语句。

2.C语言采用堆栈传参方式,将实参21H和格式化字符串偏移地址入栈。

3.C语言的函数调用约定为从右往左的顺序入栈,先push第一个实参33,然后再push第二个实参。

4.C语言的函数由调用者负责堆栈平衡。push两个实参入栈,每个实参占用4个字节,一共占用8个字节,执行call指令时,压入32位返回地址,执行ret指令时,将返回地址pop到指令指针寄存器eip中。实参占用的8个字节由add esp,8释放,至此全部堆栈空间已被释放。堆栈空间如图2-1所示。

                                图2-1 示例二堆栈框架

实验四:计算整数的差并显示结果

VS新建项目2-1-2.c:

/*

显示整数11和22的差

*/

#include <stdio.h>//C标准库输入输出头文件

int main(void)//函数头

{

  printf("%d", 11 - 22);  //%d用十进制数显示整数11-22的差

  return 0;//结束返回

   }

●输出结果:-11。

练习

1、请读者将2-1-2.c翻译成汇编语言实现。

2、请读者分析2-1-2.c的反汇编代码。

实验五:格式化字符串和转换说明

VS新建项目2-1-3.c:

/*

人性化的显示整数11和22的和

*/

#include <stdio.h>//C标准库输入输出头文件

int main(void)//函数头

{

    ​//%d用十进制数显示整数11+22的和

    ​printf("15与22的和是%d。\n", 11 + 22);//'\n'是换行符,ASCII码值是0AH

    ​return 0;//结束返回

   }

●输出结果:15与22的和是33。

练习

1、请读者将2-1-3.c翻译成汇编语言实现。注意:需要将Notepad++字符集设置为中文简体,“编码”>“编码字符集”>“中文”>“GB2312中文简体”。

2、请读者分析2-1-3.c的反汇编代码。

实验六:分行显示一

VS新建项目2-1-4.c:

/*

打招呼并进行自我介绍

*/

#include <stdio.h>//C标准库输入输出头文件

int main(void)//函数头

{

    ​printf("您好!我叫编程达人。\n");//'\n'是换行符,ASCII码值是0AH

    ​return 0;//结束返回

   }

●输出结果:您好!我叫编程达人。

实验七:分行显示二

VS新建项目2-1-5.c:

/*

打招呼并进行自我介绍

*/

#include <stdio.h>//C标准库输入输出头文件

int main(void)//函数头

{

    ​printf("您好!\n我叫编程达人。\n");//两个换行符

    ​return 0;//结束返回

   }

●输出结果:

您好!

我叫编程达人。

实验八:分行显示三

VS新建项目2-1-6.c:

/*

打招呼并进行自我介绍

*/

#include <stdio.h>//C标准库输入输出头文件

int main(void)//函数头

{

  printf("您好!\n");

  printf("我叫编程达人。\n");

  return 0;//结束返回

}

●输出结果:

您好!

我叫编程达人。

实验九:响铃

VS新建项目2-1-7.c:

/*

打招呼并3次响铃

*/

#include <stdio.h>//C标准库输入输出头文件

int main(void)//函数头

{

  printf("您好!\a\a\a\n");//转义字符'\a'响铃

  return 0;//结束返回

}

●输出结果:您好!+3次响铃。

结论

1.在实验六、实验七和实验八中,我们可以在格式化常量字符串中灵活使用换行符’\n’实现换行,也可以多次调用printf函数实现换行输出。可以根据实际需要采用不同的方案。如果为了增加代码的可读性,方便注释,可以采用实验八的方案。

2.在实验九中,我们通过输出转义字符’\a’向屏幕输出响铃。

3.在C语言中,类似’\n’换行符和’\a’响铃这样的特殊符号称为转义字符,后面的章节中我们会接触更多的转义字符。

4.字符串常量,又称字面量,定义在全局常量区。像"ABC"和"您好!"这样用双引号括起来的一连串的文字称为字符串常量。在代码中,我们通过字符串常量在全局常量区的偏移地址引用字符串常量。当我们引用常量字符串时,其实引用的是它的地址,即指针。

练习

1、请读者将实验六、实验七、实验八和实验九的C语言代码翻译成汇编语言实现。

2、请读者分析2-1-4.c、2-1-5.c、2-1-6.c、2-1-7.c的反汇编代码。

C语言中的符号

C语言通过大量的符号来简化代码。C语言符号的命名如表2-1所示。

+  加号、正号、加

{  左大括号

-       减号、负号、连字符、减

}  右大括号

*  星号、乘号、米号、星

[  左方括号、左中括号

/  斜线、除号

]  右方括号、右中括号

\  反斜线

<   小于

¥ 货币符号

>   大于

%  百分号

?  问号

.  点

! 感叹号

,  逗号

&   and符

:  冒号

~  波浪线

;  分号

^  音调符号

‘  单引号

#  井号

“  双引号

_  下划线

(  左括号、左圆括号、左小括号

=  等号、等于

)  右括号、右圆括号、右小括号

|  竖线

表2-1 C语言中的符号

​本文摘自编程达人系列教材《汇编的角度——C语言》。

  • 11
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值