# Legacy boot E820 entries written to low memory

In another post of mine, there was some discussion about a small area just above (see end of page @) BDA (500H - 534H) that handles DOS print screen. As not to interfere with this, as it would only gain me three entries anyway, map data will begin @ 540H. The addresses for this snippet are offsets from 838H, therefore, 838H + 2BH - 540H = 323H (803) bytes can be overwritten. The code could be shortened by hard coding maximum 40 entries, but I want this to stay relative.

Code is fashioned somewhat after this example albeit it is really bloated, with functionality that I don't think is really necessary.

Begin by initializing segment registers and ES:DI is the pointer to buffer for INT 15H.

 0  B85400            mov ax, 0x54          ; Just above BDA
3  8EC0              mov es, ax
5  8ED8              mov ds, ax
7  31FF              xor di, di


Everything from 540H to offset 2BH (863H) can be overwritten. Doubt seriously any system will have 40 entries, but one never knows.

 9  8CC9              mov cx, cs            ; Base segment of this code
B  C1E104            shl cx, 4             ; Convert to absolute addr
E  81C16302          add cx, 0x263         ; Offset from CS*16 to 2DH
12  C1E004            shl ax, 4             ; Convert code segment
15  29C1              sub cx, ax            ; Total bytes


At the first iteration, the length of each entry is returned in CL, which is 20, then it will be calculated how many entries will fit in this space, meanwhile this value needs to be preserved.

17  894E01            mov [bp+1], cx


Finally, EBX, ECX, EDX & AX need to be setup for INT 15H

1A  6631C9            xor ecx, ecx
1D  6689CB            mov ebx, ecx
20  B120              mov cl, 0x20
22  66BA50414D53      mov edx, 0x534d4150    ; = 'SMAP'

NOTE: Interrupt doesn't care about high order bits (31-16) of EAX. This might be
the case with ECX & EBX too, but I haven't experimented with that.

28  B820E8            mov ax, 0xe820


Infinite loop until one of six conditions occurs

2B  50                push ax
2C  6652              push edx
2E  CD15              int  15H
30  7233              jc   65             ; Continue until CF = 1


Continuation counter in BL is the next most significant value to be evaluated.

32  80FB01            cmp bl, 1
35  722E              jc  65                ; BL = 0, last entry has been read
37  770F              ja  0x48              ; BL > 1 continue reading entries


For some reason, only on first iteration does the signature in EDX need to be compared

39  6639D0            cmp eax, edx
3C  7527              jnz 65                ; EAX <> 'SMAP'

Calculation of max entries can be made now which will equal 40 in this version
3E  8B4601            mov ax, [bp+1]
41  31D2              xor dx, dx
43  F7F1              div cx                ; Probably 14H (20)
45  894601            mov [bp+1], ax


Unless I'm missing something, the linked example set first byte of next entry to 1. If that byte is overwritten, it has something to do with ACPI 3.0, but CL being greater than 20 does the same. Is my thinking flawed?

48  E316              jcxz 60
4A  80F914            cmp  cl, 20
4D  7711              ja   60


Haven't quite figured out why BIOS would return a zero length entry, but those entries are simply ignored by doing this

4F  668B4508          mov eax,[di+8]         ; Read high order bits
53  660B450C          or  eax,[di+12]        ; ZF = 1, null length entry
57  7407              jz  60


Have we run out of space yet, which is very unlikely

59  FE4E01            dec [bp+1]
5C  7407              jz  65


Point to next position and restore AX & EDX for next round

5E  01CF              add di,cx
60  665A              pop edx
62  58                pop ax
63  EBC6              jmp 2B

This is where error conditions will be evaluated, but at this point
not really sure what that has to be yet.

65  90                nop

• am I the only one who does not understand what kind of reaview you expect from us in those questions? – Paweł Łukasik Jul 4 '17 at 11:37
• @PawełŁukasik What's more likely the case is I misinterpreted what code review actually means. There are a plethora of sites, that the fundamental premise is to resolve code that has errors or help someone that is just dazed and confused. All of my code is tested in emulators like BOCHs, DOSBOX and on real hardware running Dos 6.22, bootable USB and Fixed media. So my code does what it supposed to, but maybe not the most efficient way as is evidenced by the responses on a couple of other posts. The operative word being reviewed aka seeking others opinions. – Shift_Left Jul 4 '17 at 13:33
• I think it's correct what you assumed from code review . What I would expect is some kind of questions at the end like "can this be done more optimal?" or "is there a better way to approch to this" as if I look at those right now there's nothing wrong with your code and there is no area you would like to improve there. What I also fear that all your questions are connected and one would have to go from the first one to fully do the review here – Paweł Łukasik Jul 4 '17 at 14:45
• That is a good idea, as now, those questions are insidiously embedded in description and comments. A summary at the beginning or end will definitely make it easier for respondents. – Shift_Left Jul 4 '17 at 14:59
• You're right about the connectivity, especially from my perspective, but my hope is each posting stands on its own regardless what comes before or after. I had thought of waiting until the end, but by that time, this real-mode stage will be almost 900 lines. Maybe that would be just a little too much to digest at one time. My methodology will change as I can't know what I don't know if someone doesn't say something. I am pleased though, that in the last week or so, all the feedback has been constructive. – Shift_Left Jul 4 '17 at 15:06