How can software determine the amount of power or charge left in a battery (like an iPhone battery or a laptop battery)?
There are quite a few different methods in use, all of which have their pros and cons.
One of the simplest is to just measure the voltage out of the battery. As the battery is being charged or dischared, the output voltge will vary, as demonstrated in this graph from digikey:
Of course, the curve will vary wildly by types of batteries as well as temperature and other conditions.
Another method I have seen used is to monitor the current draw from the battery by means of a very small resistor and current sense amplifier. By knowing how much capacity should be in the battery, and knowing how long the battery has been operated at specific current levels, one could estimate how much charge is remaining.
These are just a couple of basic examples. There are many integrated chips and circuits designed specifically for the purpose of monitoring power consumption.
A more detailed explanation can be found at Battery University.
ACPI is the biggest practical example I'm aware of. It serves as a standard for power monitoring, control, and everything in-between. It replaced older standards that placed responsibility for power monitoring on the BIOS, which in turn required dependence on chip firmware for reporting the necessary information to the BIOS (charge levels, depletion rates). The idea was that ACPI would standardize communication between hardware and the operating system. This SU post provides a simplified example. In a laptop for example, the firmware on the motherboard can accept commands from the operating system to read and set power states.
As for the hardware for determining the amount of charge left in a battery, it will depend firstly on the type of battery. Different designs have different discharge voltage curves. Depending on the curve, simply measuring voltage drop could provide a basic insight. However, laptops and iphones are more likely to use Li-Ion batteries that have relatively flat voltage discharge curves for the majority of their discharge. By the time you measure a voltage drop, it means the battery is nearing empty. Coulomb counting can do a reasonable job of determining the state of the charge in the battery, assuming that basic characteristics and skew are accounted for. That is, a circuit can measure how much current went into a battery on a charge and for how long, and determine from this and other stored information about the battery, how much current will go out. This of course requires that you track battery state over time, and performance can still degrade and add additional skew (that can still be accounted for mathematically, however).
EDIT: This article looks like good example of the hardware that can go into monitoring the battery. This particular circuit looks to be using a current sensing setup with comparators that can monitor for various conditions and send flags for them (overvoltage was a given example). However, determining the amount of charge left can still be a hassle since power consumption isn't at all guaranteed to be linear, especially for a device like an iPhone or laptop. However, data sensing circuits, in combination with information from the device manufacturer's datasheet, can be offloaded to software to perform calculations that give a rough idea of how much charge is "left."