1.1 全局变量引发的故事
1.1.1 剖析赋值语句机器码
int gi;void main(int argc, char* argv[]){gi = 12; // 断点, 调试}
编译器VS2022
Debug->Windows->反汇编(Disassembly): Alt+F8
0053173F int 31-1.exe!_JustMyCode_Default(void):00531740 push ebp00531741 mov ebp,esp00531743 pop ebp00531744 ret00531745 int 300531746 int 300531747 int 300531748 int 300531749 int 30053174A int 30053174B int 30053174C int 30053174D int 30053174E int 30053174F int 3--- C:\Users\XXX\Desktop\OldCoder\01\1-1\1-1.c ------------------------// 1-1.cpp : This file contains the 'main' function. Program execution begins and ends there.//int gi;int main(){00531750 push ebp00531751 mov ebp,esp00531753 sub esp,0C0h00531759 push ebx0053175A push esi0053175B push edi0053175C mov edi,ebp0053175E xor ecx,ecx00531760 mov eax,0CCCCCCCCh00531765 rep stos dword ptr es:[edi]00531767 mov ecx,offset _2FFE3A17_1-1@c (053C000h)0053176C call @__CheckForDebuggerJustMyCode@4 (0531307h)gi = 12;00531771 mov dword ptr [gi (053A57Ch)],0Ch}0053177B xor eax,eax0053177D pop edi0053177E pop esi0053177F pop ebx00531780 add esp,0C0h00531786 cmp ebp,esp00531788 call __RTC_CheckEsp (0531230h)0053178D mov esp,ebp0053178F pop ebp00531790 ret--- No source file -------------------------------------------------------------
- 内存地值用十六进制表示
十六进制一般以
h(或H)结尾, 反汇编中一般省略0053176C call @__CheckForDebuggerJustMyCode@4 (0531307h)gi = 12;00531771 mov dword ptr [gi (053A57Ch)],0Ch
00531771是赋值指令mov的存放地址
为什么在汇编语言中会出现gi? VS为了帮助开发者理解, 将操作对应的符号名也显示在语句中
选择暂时将显示符号名(Show Symbol Names)从反汇编语句中去除, 就会看到纯正的汇编语句了
0053176C call 00531307gi = 12;00531771 mov dword ptr ds:[0053A57Ch],0Ch
mov指令将0Ch赋值给内存, 即0053A57Ch
0Ch:C即十进制的12mov [地址值], 存储值- ds: 数据段寄存器
对于x64
1-1.exe!__JustMyCode_Default(void):00007FF77DC11740 ret 000007FF77DC11743 int 300007FF77DC11744 int 300007FF77DC11745 int 300007FF77DC11746 int 300007FF77DC11747 int 300007FF77DC11748 int 300007FF77DC11749 int 300007FF77DC1174A int 300007FF77DC1174B int 300007FF77DC1174C int 300007FF77DC1174D int 300007FF77DC1174E int 300007FF77DC1174F int 3--- C:\Users\XXX\Desktop\OldCoder\01\1-1\1-1.c ------------------------// 1-1.cpp : This file contains the 'main' function. Program execution begins and ends there.//int gi;int main(){00007FF77DC11750 push rbp00007FF77DC11752 push rdi00007FF77DC11753 sub rsp,0E8h00007FF77DC1175A lea rbp,[rsp+20h]00007FF77DC1175F lea rcx,[00007FF77DC21000h]00007FF77DC11766 call 00007FF77DC11343gi = 12;00007FF77DC1176B mov dword ptr [00007FF77DC1C8C8h],0Ch}00007FF77DC11775 xor eax,eax00007FF77DC11777 lea rsp,[rbp+00000000000000C8h]00007FF77DC1177E pop rdi00007FF77DC1177F pop rbp00007FF77DC11780 ret--- No source file -------------------------------------------------------------
- 内存
0053A57Ch真的是gi的地址吗? mov指令真的放在内存00531771地址中吗?
0079176C call @__CheckForDebuggerJustMyCode@4 (0791307h)4: gi = 12;00791771 mov dword ptr [gi (079A57Ch)],0Ch
打印gi的地址
#include <stdio.h>int gi;void main(int argc, char* argv[]) {gi = 12;printf("gi address=%p\n", &gi);// printf("gi address=%x\n", &gi);}
