public AddressSet disassemble(AddressSetView startSet, AddressSetView restrictedSet,
			RegisterValue initialContextValue, boolean doFollowFlow) {

		AddressSet disassembledAddrs;

		disassembledAddrs = new AddressSet();

		int alignment = language.getInstructionAlignment();

		AddressRangeIterator addressRanges = startSet.getAddressRanges();
		for (AddressRange addressRange : addressRanges) {
			if (monitor.isCancelled()) {
				break;
			}

			if (disassembledAddrs.contains(addressRange.getMinAddress(),
				addressRange.getMaxAddress())) {
				continue;
			}

			AddressSet todoSubset = new AddressSet(addressRange);

			while (!todoSubset.isEmpty() && !monitor.isCancelled()) {
				Address nextAddr = todoSubset.getMinAddress();

				// Check if location is already on disassembly list
				if (disassembledAddrs.contains(nextAddr)) {
					AddressRange doneRange = disassembledAddrs.getRangeContaining(nextAddr);
					todoSubset.delete(doneRange);
					continue;
				}

				todoSubset.delete(nextAddr, nextAddr);

				// must be aligned
				if (nextAddr.getOffset() % alignment != 0) {
					continue;
				}

				Data data = listing.getUndefinedDataAt(nextAddr);
				if (data == null) {
					AddressSetView undefinedRanges = null;
					try {
						undefinedRanges =
							program.getListing().getUndefinedRanges(todoSubset, true, monitor);
						todoSubset = new AddressSet(undefinedRanges);
					}
					catch (CancelledException e) {
						break;
					}
				}
				else {
					AddressSet currentSet =
						disassemble(nextAddr, restrictedSet, initialContextValue, doFollowFlow);

					if (!currentSet.isEmpty()) {  // nothing disassembled
						todoSubset.delete(currentSet);
						disassembledAddrs.add(currentSet);
					}
				}
				if (monitor.isCancelled()) {
					break;
				}
			}
		}
		return disassembledAddrs;
	}
Attempt disassembly of all undefined code units within the specified set of addresses.
NOTE: A single instance of this Disassembler does not support concurrent
invocations of the various disassemble methods.
Disassembler must be instantiated with a Program object.
@param startSet	the minimum set of addresses to disassemble
@param restrictedSet the set of addresses that disassembling is restricted to (may be null)
@param initialContextValue initial context value to be applied at the
startAddr.  If not null this value will take precedence when combined with
any seed value or program context.
@param doFollowFlow	flag to follow references while disassembling.
@return the set of addresses that were disassembled.
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/disassemble/Disassembler.java