INT 15h AH=88h reports the memory above the first megabyte, extended memory, in kilobytes. The 8086 can address only 1 MB, so this memory exists only on a 286 or later and is reachable in protected mode, through INT 15h AH=87h (copy a block) or through an XMS driver such as HIMEM.SYS. The value comes from the CMOS, set up by the BIOS at boot.
MOV AH, 88h ; BIOS: extended memory sizeINT 15h ; AX = KB above 1 MBJC NONE1 ; CF = 1: an 8086/8088 PC, no such functionCALL PDECMOV DX, OFFSET KB1MOV AH, 09h ; DOS: print the $-string at DS:DXINT 21hJMP DONE1NONE1:MOV DX, OFFSET NO1MOV AH, 09h ; DOS: print the $-string at DS:DXINT 21hDONE1:KB1 DB " KB of extended memory free for INT 15h", 13, 10, "$"NO1 DB "no extended memory function", 13, 10, "$"PDEC PROC NEAR ; print AX in decimal; keeps every registerPUSH AXPUSH BXPUSH CXPUSH DXMOV BX, 10XOR CX, CX ; digits on the stackDECD1:XOR DX, DXDIV BX ; AX = AX / 10, DX = the last digitPUSH DXINC CXTEST AX, AXJNZ DECD1DECD2:POP DX ; the digits come back first to lastADD DL, "0"MOV AH, 02hINT 21hLOOP DECD2POP DXPOP CXPOP BXPOP AXRETPDEC ENDP
Why 0 is a normal answer
The function predates memory managers. When HIMEM.SYS (or any XMS driver) loads, it takes over extended memory and hooks INT 15h so that AH=88h returns 0: an old program that would otherwise use the memory directly through AH=87h sees none and does not overwrite what the XMS driver hands out. So 0 usually means "managed by someone else", and a program that wants extended memory asks the XMS driver (INT 2Fh AX=4300h, then its entry point). DOSBox-X has an XMS driver built in and on by default, so this call returns 0 there.
Limits
AX is 16 bits, so the answer stops at 65 535 KB, just under 64 MB, and many BIOSes cap it at 15 MB or 63 MB. For more, 386 and later BIOSes offer AX=E801h and the memory map AX=E820h. On a PC or XT the function returns CF = 1, AH = 86h.