关于微软 2012 暑期实习题第 5 题

简介:     本文中提到的题目来自于这篇文章:《2012微软暑期实习笔试题及答案》 中的第五题。这道题目是这样的:   5. What is output if you compile and execute the following code?void main() {     int ...

    本文中提到的题目来自于这篇文章:《2012微软暑期实习笔试题及答案》 中的第五题。这道题目是这样的:

 

5. What is output if you compile and execute the following code?

void main()
{
    int i = 11;
    int const *p = &i;
    p++;
    printf( "%d", *p);
}

(A) 11;  (B) 12;  (C) Garbage value;  (D) Compile error;  (E) None of above.

 

    首先,很显然这道题目第一要考察 const 的写法,也就是这个代码中 const 修饰的是指针变量 p 还是被 p 指向的整数。简单的记忆的方法就是 const 修饰的是最靠近它的东西,左侧优先。因此这句话中 const 修饰的是左侧的 int,即相当于 const int* p; 所以通常采用后者这种写法,因为后者更符合阅读(pointer to const int),不容易引发认知错误。因此,上面的代码能通过编译,即答案 (D)首先可以被排除。

 

    p++ 使 p 向高地址移动了一个 int 的距离(对于win32,4 bytes),移动后指向了什么位置呢?显然依然是一个栈上地址。但这道题目是不是就应该选(C)Gargage Value 呢?所以这道题目比较有趣,它涉及到了函数调用时 stack frame 的细节。因此我们还需要更明确的分析 stack 上的存储内容,明确 p 指向了什么,然后才能给出结论。

 

    我们先给出一个基本结论,p 被初始化指向 i (因为 i 是第一个出现的临时变量,所以 i 是最靠近返回值地址的(savedPC)),这时继续让 p 的指向向 savedPC 的方向移动一个 int 元素跨度。【注意减小 sp 相当于在栈上开辟空间,增加 sp 相当于释放栈上空间,p++ 使得向栈内方向而不是栈外方向移动,正是这种移动方向导致这道题的答案带有了争议性。我们非常希望 int 不是第一个临时变量,假设它前面还有其他变量,那么我们就可以更明确的指出 p 会指向在 i 之前出现的临时变量。可惜 i 就是第一个临时变量。假如编译器分配空间时,让 i 和 savedPC 紧邻,则这会导致 p 指向 savedPC。但幸运的是,在后面的分析中可以看到编译器竟然会在 i 和 savedPC 可能会预留出垃圾数据。】

 

    首先把上面的代码用 VC6.0 做一个实验,编译配置是 Win32 Debug,把最后一句替换成 printf("%08X\n", *p); 发现输出结果是:0012FFC0。

    然后使用 IDA 反汇编分析可执行文件。

    首先,main 函数的返回值类型和参数列表(本题目中为 void main ( void ); )不重要,不会影响生成的代码。生成的 main 函数实际上是三个参数,汇编代码对应的原型是:

 

    int main(int argc, char* argv[], char* environ[]);

 

    其中 environ 是一个废弃参数,类似 argv 它也是一个字符串数组,以 NULL 元素为截止标志,是一些"key = value"形式的系统环境变量之类的字符串。

 

    使用 VC6 debug (注意:不同编译器,不同编译选项结果不同,参考补充部分),main 函数的汇编代码如下:

 

 main            proc near               ; CODE XREF: j_main
目录
相关文章
|
6天前
|
云安全 人工智能 安全
AI被攻击怎么办?
阿里云提供 AI 全栈安全能力,其中对网络攻击的主动识别、智能阻断与快速响应构成其核心防线,依托原生安全防护为客户筑牢免疫屏障。
|
15天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
9天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
614 216
|
存储 人工智能 监控
从代码生成到自主决策:打造一个Coding驱动的“自我编程”Agent
本文介绍了一种基于LLM的“自我编程”Agent系统,通过代码驱动实现复杂逻辑。该Agent以Python为执行引擎,结合Py4j实现Java与Python交互,支持多工具调用、记忆分层与上下文工程,具备感知、认知、表达、自我评估等能力模块,目标是打造可进化的“1.5线”智能助手。
857 61
|
7天前
|
人工智能 移动开发 自然语言处理
2025最新HTML静态网页制作工具推荐:10款免费在线生成器小白也能5分钟上手
晓猛团队精选2025年10款真正免费、无需编程的在线HTML建站工具,涵盖AI生成、拖拽编辑、设计稿转代码等多种类型,均支持浏览器直接使用、快速出图与文件导出,特别适合零基础用户快速搭建个人网站、落地页或企业官网。
1292 157
|
5天前
|
编解码 Linux 数据安全/隐私保护
教程分享免费视频压缩软件,免费视频压缩,视频压缩免费,附压缩方法及学习教程
教程分享免费视频压缩软件,免费视频压缩,视频压缩免费,附压缩方法及学习教程
243 138
|
7天前
|
存储 安全 固态存储
四款WIN PE工具,都可以实现U盘安装教程
Windows PE是基于NT内核的轻量系统,用于系统安装、分区管理及故障修复。本文推荐多款PE制作工具,支持U盘启动,兼容UEFI/Legacy模式,具备备份还原、驱动识别等功能,操作简便,适合新旧电脑维护使用。
531 109