32 获取物理内存容量 下

参考

https://blog.51cto.com/13475106/category6.html及狄泰软件相关课程

获取物理内存容量

上面介绍的是基础功能,这里介绍的是高级功能操作系统-获取物理内存容量
参数的设置
操作系统-获取物理内存容量
edx是bios所需要的值,不做深究
地址范围描述结果(ARDS)
操作系统-获取物理内存容量操作系统-获取物理内存容量

代码实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
%include "inc.asm"
 
org 0x9000
 
jmp ENTRY_SEGMENT
 
[section .gdt]
 
; GDT definition
 
;                                     段基址,           段界限,       段属性
 
GDT_ENTRY       :     Descriptor        0,                0,           0
 
CODE32_DESC     :     Descriptor        0,        Code32SegLen - 1,    DA_C + DA_32
 
VIDEO_DESC      :     Descriptor     0xB8000,         0x07FFF,         DA_DRWA + DA_32
 
DATA32_DESC     :     Descriptor        0,        Data32SegLen - 1,    DA_DRW + DA_32
 
STACK32_DESC    :     Descriptor        0,         TopOfStack32,       DA_DRW + DA_32
 
; GDT end
 
GdtLen    equ   $ - GDT_ENTRY
 
GdtPtr:
 
          dw   GdtLen - 1
 
          dd   0
 
; GDT Selector
 
Code32Selector   equ (0x0001 << 3) + SA_TIG + SA_RPL0
 
VideoSelector    equ (0x0002 << 3) + SA_TIG + SA_RPL0
 
Data32Selector   equ (0x0003 << 3) + SA_TIG + SA_RPL0
 
Stack32Selector  equ (0x0004 << 3) + SA_TIG + SA_RPL0
 
; end of [section .gdt]
 
TopOfStack16    equ 0x7c00
 
[section .dat]
 
[bits 32]
 
DATA32_SEGMENT:
 
    DTOS               db  "D.T.OS!", 0
 
    DTOS_OFFSET        equ DTOS - $$
 
    HELLO_WORLD        db  "Hello World!", 0
 
    HELLO_WORLD_OFFSET equ HELLO_WORLD - $$
 
Data32SegLen equ $ - DATA32_SEGMENT
 
;
 
MEM_SIZE              times    4      db  0
 
MEM_ARDS_NUM          times    4      db  0      ; int mem_ards_num = 0;
 
MEM_ARDS              times 64 * 20   db  0
 
[section .s16]
 
[bits 16]
 
ENTRY_SEGMENT:
 
    mov ax, cs
 
    mov ds, ax
 
    mov es, ax
 
    mov ss, ax
 
    mov sp, TopOfStack16
 
    ; get InitSysMemBuf  infomation
 
    call InitSysMemBuf
 
    ; initialize GDT for 32 bits code segment
 
    mov esi, CODE32_SEGMENT
 
    mov edi, CODE32_DESC
 
    call InitDescItem
 
    mov esi, DATA32_SEGMENT
 
    mov edi, DATA32_DESC
 
    call InitDescItem
 
    mov esi, STACK32_SEGMENT
 
    mov edi, STACK32_DESC
 
    call InitDescItem
 
    ; initialize GDT pointer struct
 
    mov eax, 0
 
    mov ax, ds
 
    shl eax, 4
 
    add eax, GDT_ENTRY
 
    mov dword [GdtPtr + 2], eax
 
    ; 1. load GDT
 
    lgdt [GdtPtr]
 
    ; 2. close interrupt
 
    cli
 
    ; 3. open A20
 
    in al, 0x92
 
    or al, 00000010b
 
    out 0x92, al
 
    ; 4. enter protect mode
 
    mov eax, cr0
 
    or eax, 0x01
 
    mov cr0, eax
 
    ; 5. jump to 32 bits code
 
    jmp dword Code32Selector : 0
 
; esi    --> code segment label
 
; edi    --> descriptor label
 
InitDescItem:
 
    push eax
 
    mov eax, 0
 
    mov ax, cs
 
    shl eax, 4
 
    add eax, esi
 
    mov word [edi + 2], ax
 
    shr eax, 16
 
    mov byte [edi + 4], al
 
    mov byte [edi + 7], ah
 
    pop eax
 
    ret
 
;
 
;
 
GetMemSize:
 
    push eax
 
    push ebx
 
    push ecx
 
    push edx
 
    mov dword [MEM_SIZE], 0
 
    xor eax, eax
 
    mov eax, 0xE801
 
    int 0x15
 
    jc geterr
 
    shl eax, 10   ; eax = eax * 1024;
 
    shl ebx, 6    ; ebx = ebx * 64;
 
    shl ebx, 10   ; ebx = ebx * 1024;
 
    mov ecx, 1
 
    shl ecx, 20   ; ecx = 1MB
 
    add dword [MEM_SIZE], eax
 
    add dword [MEM_SIZE], ebx
 
    add dword [MEM_SIZE], ecx
 
    jmp getok
 
geterr:
 
    mov dword [MEM_SIZE], 0
 
getok:
 
    pop edx
 
    pop ecx
 
    pop ebx
 
    pop eax
 
    ret
 
; return
 
;    eax  --> 0 : succeed      1 : failed
 
InitSysMemBuf:
 
     push edi
 
     push ebx
 
     push ecx
 
     push edx
 
     mov edi, MEM_ARDS
 
     mov ebx, 0
 
memerr:
 
     mov dword [MEM_ARDS_NUM], 0
 
     mov eax, 1
 
doloop:
 
     mov eax, 0xE820
 
     mov edx, 0x534D4150
 
     mov ecx, 20
 
     int 0x15
 
     jc memerr
 
     add edi, 20
 
     inc dword [MEM_ARDS_NUM]
 
     cmp ebx, 0
 
     jne doloop
 
     mov eax,0
 
     jmp memok
 
memok:  
 
     pop edx
 
     pop ecx
 
     pop ebx
 
     pop edi
 
     ret
 
[section .s32]
 
[bits 32]
 
CODE32_SEGMENT:  
 
    mov ax, VideoSelector
 
    mov gs, ax
 
    mov ax, Stack32Selector
 
    mov ss, ax
 
    mov eax, TopOfStack32
 
    mov esp, eax
 
    mov ax, Data32Selector
 
    mov ds, ax
 
    mov ebp, DTOS_OFFSET
 
    mov bx, 0x0C
 
    mov dh, 12
 
    mov dl, 33
 
    call PrintString
 
    mov ebp, HELLO_WORLD_OFFSET
 
    mov bx, 0x0C
 
    mov dh, 13
 
    mov dl, 31
 
    call PrintString
 
    jmp $
 
; ds:ebp    --> string address
 
; bx        --> attribute
 
; dx        --> dh : row, dl : col
 
PrintString:
 
    push ebp
 
    push eax
 
    push edi
 
    push cx
 
    push dx
 
print:
 
    mov cl, [ds:ebp]
 
    cmp cl, 0
 
    je end
 
    mov eax, 80
 
    mul dh
 
    add al, dl
 
    shl eax, 1
 
    mov edi, eax
 
    mov ah, bl
 
    mov al, cl
 
    mov [gs:edi], ax
 
    inc ebp
 
    inc dl
 
    jmp print
 
end:
 
    pop dx
 
    pop cx
 
    pop edi
 
    pop eax
 
    pop ebp
 
    ret
 
Code32SegLen    equ    $ - CODE32_SEGMENT
 
[section .gs]
 
[bits 32]
 
STACK32_SEGMENT:
 
    times 1024 * 4 db 0
 
Stack32SegLen equ $ - STACK32_SEGMENT
 
TopOfStack32  equ Stack32SegLen - 1

 

操作系统-获取物理内存容量

结果分析

首先通反编译找到函数的调用地址,然后对该处设置地址,同时也对下个地址进行设置,同时打上断点,通过书写的函数,找到所需查看的地址,如下图所示
操作系统-获取物理内存容量操作系统-获取物理内存容量操作系统-获取物理内存容量操作系统-获取物理内存容量
首先查看全局函数0x904d的内存,发下为0是我们所需的结果,查看寄存器eax寄存器为0,说明调用成功,再次查看0x904d发现其为6,这次需要查看数组前六个元素,通过数组地址0x9051,发现其有起始地址,长度,类型,通过打印六次之后,所打印的结果为0,说明得到内存信息
操作系统-获取物理内存容量操作系统-获取物理内存容量操作系统-获取物理内存容量

 

 

 

 

posted on   lh03061238  阅读(102)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
历史上的今天:
2020-02-24 浅谈 C++ 中的 new/delete 和 new[]/delete[] (转)

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示