以下是对您提供的汇编代码和变量描述的整理:
整数类型与全局变量:xdbg查看全局变量
在使用调试工具(如 xdbg)时,查看全局变量的表示范围非常重要,以帮助理解不同数据类型的取值范围和存储方式。以下是常见的整数类型及其表示范围。
1. 带符号整数类型
int
- 占用内存:通常为 4 字节(32 位)
- 表示范围:
-2^31到2^31 - 1- 范围:
-2,147,483,648到2,147,483,647
- 范围:
short
- 占用内存:2 字节(16 位)
- 表示范围:
-2^15到2^15 - 1- 范围:
-32,768到32,767
- 范围:
char
- 占用内存:1 字节(8 位)
- 表示范围:
-2^7到2^7 - 1- 范围:
-128到127
- 范围:
2. 无符号整数类型
BYTE
- 占用内存:1 字节(8 位)
- 表示范围:
0到2^8 - 1- 范围:
0到255
- 范围:
WORD
- 占用内存:2 字节(16 位)
- 表示范围:
0到2^16 - 1- 范围:
0到65,535
- 范围:
DWORD
- 占用内存:4 字节(32 位)
- 表示范围:
0到2^32 - 1- 范围:
0到4,294,967,295
- 范围:
typedef 类型别名
通过 typedef 可以为某些类型创建别名,以方便在代码中使用:
typedef unsigned long DWORD;
typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned short WORD;
汇编代码分析
接下来是两段调试中的汇编代码,它们展示了程序中如何操作带符号和无符号的全局变量,以及计算过程。
汇编代码段 1
00007FF66B7A1930 <project2.ma | 40:55 | push rbp
00007FF66B7A1932 | 57 | push rdi
00007FF66B7A1933 | 48:81EC 08010000 | sub rsp,108
00007FF66B7A193A | 48:8D6C24 20 | lea rbp,qword ptr ss:[rsp+20]
00007FF66B7A193F | 48:8D0D AE070100 | lea rcx,qword ptr ds:[<__745DA50B_FileName@cpp>]
00007FF66B7A1946 | E8 2FFAFFFF | call project2.7FF66B7A137A
00007FF66B7A194B | 90 | nop
00007FF66B7A194C | 8B05 B2B60000 | mov eax,dword ptr ds:[<unsigned long b>]
00007FF66B7A1952 | 8B0D A8B60000 | mov ecx,dword ptr ds:[<unsigned long a>]
00007FF66B7A1958 | 2BC8 | sub ecx,eax
00007FF66B7A195A | 8BC1 | mov eax,ecx
00007FF66B7A195C | 8905 9EB80000 | mov dword ptr ds:[<unsigned long c>],eax
00007FF66B7A1962 | 44:8B0D 97B80000 | mov r9d,dword ptr ds:[<unsigned long c>]
00007FF66B7A1969 | 44:8B05 94B60000 | mov r8d,dword ptr ds:[<unsigned long b>]
00007FF66B7A1970 | 8B15 8AB60000 | mov edx,dword ptr ds:[<unsigned long a>]
00007FF66B7A1976 | 48:8D0D AB920000 | lea rcx,qword ptr ds:[<"helloword!%d-%d=%d"...>]
00007FF66B7A197D | E8 18F8FFFF | call project2.7FF66B7A119A
00007FF66B7A1982 | 90 | nop
00007FF66B7A1983 | FF15 7FF90000 | call qword ptr ds:[<&getchar>]
00007FF66B7A1989 | 8945 04 | mov dword ptr ss:[rbp+4],eax
00007FF66B7A198C | 33C0 | xor eax,eax
00007FF66B7A198E | 48:8DA5 E8000000 | lea rsp,qword ptr ss:[rbp+E8]
00007FF66B7A1995 | 5F | pop rdi
00007FF66B7A1996 | 5D | pop rbp
00007FF66B7A1997 | C3 | ret
汇编代码段 2
00007FF752E91930 <project2.ma | 40:55 | push rbp
00007FF752E91932 | 57 | push rdi
00007FF752E91933 | 48:81EC 08010000 | sub rsp,108
00007FF752E9193A | 48:8D6C24 20 | lea rbp,qword ptr ss:[rsp+20]
00007FF752E9193F | 48:8D0D 22070100 | lea rcx,qword ptr ds:[<__745DA50B_FileName@cpp>]
00007FF752E91946 | E8 2FFAFFFF | call project2.7FF752E9137A
00007FF752E9194B | 90 | nop
00007FF752E9194C | 8B05 B2B60000 | mov eax,dword ptr ds:[<int b>]
00007FF752E91952 | 8B0D A8B60000 | mov ecx,dword ptr ds:[<int a>]
00007FF752E91958 | 2BC8 | sub ecx,eax
00007FF752E9195A | 8BC1 | mov eax,ecx
00007FF752E9195C | 8905 9EB80000 | mov dword ptr ds:[<int c>],eax
00007FF752E91962 | 44:8B0D 97B80000 | mov r9d,dword ptr ds:[<int c>]
00007FF752E91969 | 44:8B05 94B60000 | mov r8d,dword ptr ds:[<int b>]
00007FF752E91970 | 8B15 8AB60000 | mov edx,dword ptr ds:[<int a>]
00007FF752E91976 | 48:8D0D AB920000 | lea rcx,qword ptr ds:[<"helloword!%d-%d=%d"...>]
00007FF752E9197D | E8 18F8FFFF | call project2.7FF752E9119A
00007FF752E91982 | 90 | nop
00007FF752E91983 | FF15 7FF90000 | call qword ptr ds:[<&getchar>]
00007FF752E91989 | 8945 04 | mov dword ptr ss:[rbp+4],eax
00007FF752E9198C | 33C0 | xor eax,eax
00007FF752E9198E | 48:8DA5 E8000000 | lea rsp,qword ptr ss:[rbp+E8]
00007FF752E91995 | 5F | pop rdi
00007FF752E91996 | 5D | pop rbp
00007FF752E91997 | C3 | ret
基址与全局变量的关系
在调试工具(如 xdbg)中查看全局变量时,可以通过全局变量的内存地址和程序的基址(Base Address)关系来判断它是否属于全局变量。
基址是什么?
基址是程序加载到内存时的起始地址。在汇编层面,程序中的全局变量通常存储在 .data 或 .bss 段,其地址是相对于程序的基址的固定偏移量。因此:
- 如果变量的地址是基址加上一个固定偏移量,那么这个变量就是全局变量。
通过汇编代码分析基址与全局变量
以下是加入基址的解析:
示例汇编代码
00007FF752E9194C | mov eax, dword ptr ds:[<int b>] ; 将变量 b 的值加载到 eax 中
dword ptr ds:[<int b>]表示从内存中加载一个int类型的值。- 地址
<int b>是一个固定的偏移量,相对于程序的基址计算得来。 - 如果基址为
0x00007FF752E00000,那么<int b>的实际地址为:实际地址 = 基址 + 偏移量
完整代码分析
以以下代码为例:
00007FF752E91930 <project2.ma | 40:55 | push rbp
00007FF752E91932 | 57 | push rdi
00007FF752E9194C | 8B05 B2B60000 | mov eax, dword ptr ds:[<int b>]
00007FF752E91952 | 8B0D A8B60000 | mov ecx, dword ptr ds:[<int a>]
00007FF752E9195C | 8905 9EB80000 | mov dword ptr ds:[<int c>], eax
在调试工具中:
- 基址 =
0x00007FF752E00000 - 偏移量:
- 变量
b的地址:0xB2B6 - 变量
a的地址:0xA8B6 - 变量
c的地址:0x9EB8
- 变量
通过计算,这些地址的实际位置为:
变量 b 的地址 = 基址 + 偏移量 b = 0x00007FF752E00000 + 0xB2B6 = 0x00007FF752E0B2B6
变量 a 的地址 = 基址 + 偏移量 a = 0x00007FF752E00000 + 0xA8B6 = 0x00007FF752E0A8B6
变量 c 的地址 = 基址 + 偏移量 c = 0x00007FF752E00000 + 0x9EB8 = 0x00007FF752E09EB8
这些地址在 .data 段中,属于全局变量。
如何判断基址相关变量是全局变量?
-
是否是固定偏移量:
- 全局变量地址 = 程序基址 + 偏移量。
- 偏移量是固定的,与程序的逻辑地址分布有关。
-
查看存储段:
- 调试工具中,如果变量地址属于
.data或.bss段,通常是全局变量。 - 全局变量在编译后存储在这些特定的段中。
- 调试工具中,如果变量地址属于
-
动态地址重定位(ASLR):
- 如果程序启用了 ASLR(地址空间布局随机化),基址会动态变化,但偏移量相对于基址仍然固定。
示例:基址与全局变量
通过上述分析,可以得出以下结论:
- 在
xdbg等调试器中,变量a、b和c的地址均是基址加上固定偏移量,因此它们是全局变量。 - 基址的使用是判断全局变量的重要标志之一。
总结
-
基址与偏移量关系:
- 全局变量的地址是基址加上固定偏移量。
- 偏移量相对于基址是固定的,与程序逻辑地址分布有关。
-
判断全局变量:
- 如果变量地址属于
.data或.bss段,并且其地址可以通过基址和固定偏移量计算得出,则可以判断为全局变量。
- 如果变量地址属于
-
调试工具中全局变量的识别:
- 使用
xdbg查看全局变量时,观察变量的内存地址是否相对于基址是固定的,可以确认它是全局变量。
- 使用

7546

被折叠的 条评论
为什么被折叠?



