private void compareBytes(AddressRange limitedRange, AddressSet differences,
			TaskMonitor monitor) throws MemoryAccessException, CancelledException {

		Memory mem1 = program1.getMemory();
		Memory mem2 = program2.getMemory();
		byte[] temp1 = new byte[BYTE_DIFF_GRAB_SIZE];
		byte[] temp2 = new byte[BYTE_DIFF_GRAB_SIZE];
		int nBytes;
		Address min = limitedRange.getMinAddress();
		Address max = limitedRange.getMaxAddress();
		Address addr = min;
		Address addr2 = SimpleDiffUtility.getCompatibleAddress(program1, addr, program2);
		Address endAddr = max;
		int addressSize = min.getAddressSpace().getAddressableUnitSize();
		// There may be multiple blocks that make up the range in each memory.
		do {
			MemoryBlock b1 = mem1.getBlock(addr);
			Address addrCompatibleWith2 =
				SimpleDiffUtility.getCompatibleAddress(program1, addr, program2);
			MemoryBlock b2 = mem2.getBlock(addrCompatibleWith2);
//			if (addr instanceof SegmentedAddress) {
//				int segment = ((SegmentedAddress)b1.getStart()).getSegment();
//				addr = ((SegmentedAddress)addr).normalize(segment);
//			}
			Address b1End = b1.getEnd();
			Address b2End = b2.getEnd();
			Address b2EndCompatibleWith1 =
				SimpleDiffUtility.getCompatibleAddress(program2, b2End, program1);
			// endAddr will hold the end address for checking the current blocks.
			endAddr = (b1End.compareTo(max) < 0) ? b1End : max;
			if (b2EndCompatibleWith1 != null) {
				endAddr =
					(b2EndCompatibleWith1.compareTo(endAddr) < 0) ? b2EndCompatibleWith1 : endAddr;
			}
			long size = endAddr.subtract(addr) + 1;
			for (int index = 0; index < size; index += nBytes) {
				int bytesToGet = (int) Math.min((size - index), BYTE_DIFF_GRAB_SIZE);
				int n1 = b1.getBytes(addr, temp1, 0, bytesToGet);
				int n2 = b2.getBytes(addr2, temp2, 0, bytesToGet);
				nBytes = Math.min(n1, n2);
				Address start = null;
				boolean same = true;
				for (int i = 0; i < nBytes; i++) {
					if (temp1[i] != temp2[i]) {
						if (same) {
							same = false;
							start = addr.addWrap(i);
						}
//						Address byteAddr = addr.addWrap(i);
//						if (!differences.contains(byteAddr)) {
//							CodeUnit cu1 = listing1.getCodeUnitContaining(byteAddr);
//							CodeUnit cu2 = listing2.getCodeUnitContaining(byteAddr);
//							Address min1 = cu1.getMinAddress();
//							Address min2 = cu2.getMinAddress();
//							Address max1 = cu1.getMaxAddress();
//							Address max2 = cu2.getMaxAddress();
//							Address addrMin =
//								min1.compareTo(min2) < 0 ? min1 : min2;
//							Address addrMax =
//								max1.compareTo(max2) > 0 ? max1 : max2;
//							differences.addRange(addrMin, addrMax);
//						}
					}
					else {
						if (!same) {
							same = true;
							differences.addRange(start, addr.addWrap(i - 1));
						}
					}
				}
				if (!same) {
					same = true;
					differences.addRange(start, addr.addWrap(nBytes - 1));
				}
				monitor.setProgress(monitor.getProgress() + (nBytes / addressSize));
				monitor.setMessage(monitorMsg + ": " + addr.toString(showAddressSpace));
				try {
					addr = addr.addNoWrap(nBytes);
					addr2 = SimpleDiffUtility.getCompatibleAddress(program1, addr, program2);
				}
				catch (AddressOverflowException e) {
					// Do nothing.
				}
				checkCancelled(monitor);
			}
			checkCancelled(monitor);
		}
		while (endAddr.compareTo(max) < 0);
	}
Creates an address set indicating the differences between program1 and
program2 of the specified type.
The addresses in this address set are derived from program1
and put into diffAddrSets using the diffType number as an index.
@param diffType the type of difference to look for between the programs.
@param monitor the task monitor for indicating the progress of
determining differences. This monitor reports the progress to the user.
@throws ProgramConflictException if the two programs are not comparable since registers differ.
@throws CancelledException if the user cancelled the Diff.
Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramDiff.java