Index: kernel/arch/ia32/src/mm/frame.c
===================================================================
--- kernel/arch/ia32/src/mm/frame.c	(revision a55ddc6414f979c04363b992f2620a167889bd1b)
+++ kernel/arch/ia32/src/mm/frame.c	(revision ad12b5ea675f6fa2b88cd868c39d5005c6cd86da)
@@ -57,21 +57,9 @@
 	
 	for (i = 0; i < e820counter; i++) {
-		uint64_t base = e820table[i].base_address;
-		uint64_t size = e820table[i].size;
-		uintptr_t limit = config.identity_size;
+		uintptr_t base = (uintptr_t) e820table[i].base_address;
+		size_t size = (size_t) e820table[i].size;
 		
-		if (low) {
-			if (base > limit)
-				continue;
-			if (base + size > limit)
-				size = limit - base;
-		} else {
-			if (base + size <= limit)
-				continue;
-			if (base <= limit) {
-				size -= limit - base;
-				base = limit;
-			}
-		}
+		if (!frame_adjust_zone_bounds(low, &base, &size))
+			continue;
 		
 		if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) {
@@ -93,5 +81,4 @@
 				    ZONE_AVAILABLE | ZONE_LOWMEM);
 			} else {
-				printf("count=%lld\n", (long long int) count);
 				conf = zone_external_conf_alloc(count);
 				zone_create(pfn, count, conf,
Index: kernel/generic/include/mm/frame.h
===================================================================
--- kernel/generic/include/mm/frame.h	(revision a55ddc6414f979c04363b992f2620a167889bd1b)
+++ kernel/generic/include/mm/frame.h	(revision ad12b5ea675f6fa2b88cd868c39d5005c6cd86da)
@@ -159,4 +159,5 @@
 
 extern void frame_init(void);
+extern bool frame_adjust_zone_bounds(bool, uintptr_t *, size_t *);
 extern void *frame_alloc_generic(uint8_t, frame_flags_t, size_t *);
 extern void *frame_alloc(uint8_t, frame_flags_t);
Index: kernel/generic/src/mm/frame.c
===================================================================
--- kernel/generic/src/mm/frame.c	(revision a55ddc6414f979c04363b992f2620a167889bd1b)
+++ kernel/generic/src/mm/frame.c	(revision ad12b5ea675f6fa2b88cd868c39d5005c6cd86da)
@@ -1264,4 +1264,36 @@
 }
 
+/** Adjust bounds of physical memory region according to low/high memory split.
+ *
+ * @param low[in]	If true, the adujstment is performed to make the region
+ *			fit in the low memory. Otherwise the adjustment is
+ *			performed to make the region fit in the high memory.
+ * @param basep[inout]	Pointer to a variable which contains the region's base
+ *			address and which may receive the adjusted base address.
+ * @param sizep[inout]	Pointer to a variable which contains the region's size
+ *			and which may receive the adjusted size.
+ * @retun		True if the region still exists even after the
+ *			adjustment, false otherwise.
+ */
+bool frame_adjust_zone_bounds(bool low, uintptr_t *basep, size_t *sizep)
+{
+	uintptr_t limit = config.identity_size;
+
+	if (low) {
+		if (*basep > limit)
+			return false;
+		if (*basep + *sizep > limit)
+			*sizep = limit - *basep;
+	} else {
+		if (*basep + *sizep <= limit)
+			return false;
+		if (*basep <= limit) {
+			*sizep -= limit - *basep;
+			*basep = limit;
+		}
+	}
+	return true;
+}
+
 /** Return total size of all zones.
  *
