- 第一章 CPU 简介
- 第二章 Hello,world!
- 第三章 函数开始和结束
- 第四章 栈
- Chapter 5 printf() 与参数处理
- Chapter 6 scanf()
- CHAPER7 访问传递参数
- Chapter 8 一个或者多个字的返回值
- Chapter 9 指针
- Chapter 10 条件跳转
- 第 11 章 选择结构 switch()/case/default
- 第 12 章 循环结构
- 第 13 章 strlen()
- Chapter 14 Division by 9
- chapter 15 用 FPU 工作
- Chapter 16 数组
- Chapter 17 位域
- 第 18 章 结构体
- 19 章 联合体
- 第二十章 函数指针
- 第 21 章 在 32 位环境中的 64 位值
- 第二十二章 SIMD
- 23 章 64 位化
- 24 章 使用 x64 下的 SIMD 来处理浮点数
- 25 章 温度转换
- 26 章 C99 的限制
- 27 章 内联函数
- 第 28 章 得到不正确反汇编结果
- 第 29 章 花指令
- 第 30 章 16 位 Windows
- 第 31 章 类
- 三十二 ostream
- 34.2.2 MSVC
- 34.2.3 C++ 11 std::forward_list
- 34.3 std::vector
- 34.4 std::map and std::set
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
18.2 让我们用 malloc() 为结构体分配空间
但是,有时候把结构体放在堆中而不是栈上却更简单:
#!cpp
#include <windows.h>
#include <stdio.h>
void main()
{
SYSTEMTIME *t;
t=(SYSTEMTIME *)malloc (sizeof (SYSTEMTIME));
GetSystemTime (t);
printf ("%04d-%02d-%02d %02d:%02d:%02d
",
t->wYear, t->wMonth, t->wDay,
t->wHour, t->wMinute, t->wSecond);
free (t);
return;
};
让我们用优化/Ox 编译一下它,看看我们得到什么东西
清单 18.4: 优化的 MSVC
#!bash
_main PROC
push esi
push 16 ; 00000010H
call _malloc
add esp, 4
mov esi, eax
push esi
call DWORD PTR __imp__GetSystemTime@4
movzx eax, WORD PTR [esi+12] ; wSecond
movzx ecx, WORD PTR [esi+10] ; wMinute
movzx edx, WORD PTR [esi+8] ; wHour
push eax
movzx eax, WORD PTR [esi+6] ; wDay
push ecx
movzx ecx, WORD PTR [esi+2] ; wMonth
push edx
movzx edx, WORD PTR [esi] ; wYear
push eax
push ecx
push edx
push OFFSET $SG78833
call _printf
push esi
call _free
add esp, 32 ; 00000020H
xor eax, eax
pop esi
ret 0
_main ENDP
所以,sizeof(SYSTEMTIME) = 16, 这正是 malloc 所分配的字节数。它返回了刚刚分配的地址空间,这个指针存在 EAX 寄存器里。然后,这个指针会被移动到 ESI 结存器中, GetSystemTime() 会用它来存储返回值,这也就是为什么这里分配完之后并没有把 EAX 放到某个地方保存起来,而是直接使用它的原因。
新指令:MOVZX(Move with Zero eXtent, 0 扩展移动)。它可以说是和 MOVSX 基本一样(13.1.1 节),但是,它把其他位都设置为 0。这是因为 printf() 需要一个 32 位的整数,但是我们的结构体里面是 WORD,这只有 16 位厂。这也就是为什么从 WORD 复制到 INT 时第 16~31 位必须清零的原因了。因为,如果不清除的话,剩余位可能有之前操作留下来的干扰数据。
在下面这个例子里面,我可以用 WORD 数组来重现这个结构:
#!cpp
#include <windows.h>
#include <stdio.h>
void main()
{
WORD *t;
t=(WORD *)malloc (16);
GetSystemTime (t);
printf ("%04d-%02d-%02d %02d:%02d:%02d
",
t[0] /* wYear */, t[1] /* wMonth */, t[3] /* wDay */,
t[4] /* wHour */, t[5] /* wMinute */, t[6] /* wSecond */);
free (t);
return;
};
我们得到:
#!bash
$SG78594 DB ’%04d-%02d-%02d %02d:%02d:%02d’, 0aH, 00H
_main PROC
push esi
push 16 ; 00000010H
call _malloc
add esp, 4
mov esi, eax
push esi
call DWORD PTR __imp__GetSystemTime@4
movzx eax, WORD PTR [esi+12]
movzx ecx, WORD PTR [esi+10]
movzx edx, WORD PTR [esi+8]
push eax
movzx eax, WORD PTR [esi+6]
push ecx
movzx ecx, WORD PTR [esi+2]
push edx
movzx edx, WORD PTR [esi]
push eax
push ecx
push edx
push OFFSET $SG78594
call _printf
push esi
call _free
add esp, 32 ; 00000020H
xor eax, eax
pop esi
ret 0
_main ENDP
同样,我们可以看到编译结果和之前一样。个人重申一次,你不应该在写代码的时候用这么晦涩的方法来表达它。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论