Each page has its own cursor position in the BIOS data area: a word per page from 40h:50h, with the column in the low byte and the row in the high byte, the same layout as DX here. Function 02h stores DX for page BH, and if BH is the active page, the hardware cursor on the screen moves too. Nothing is written.

Rows and columns count from 0. In 80×25 text the top-left cell is DH = 0, DL = 0 and the bottom-right one DH = 24 (18h), DL = 79 (4Fh). Since DH is the row and DL the column, one MOV DX, 0C28h selects row 12, column 40.

Everything that writes "at the cursor" uses this position: functions 09h, 0Ah and 0Eh, and DOS console output, which goes through the BIOS. Here the cursor jumps to column 40 of its row, and DOS prints from there:

Prints "column 40"; on the screen it starts at column 40, in the middle of the line.
MOV AH, 03h ; where is the cursor? DH = row, DL = column
MOV BH, 0 ; page 0
INT 10h
MOV AH, 02h ; set the cursor position
MOV BH, 0
MOV DL, 40 ; the same row (DH), column 40
INT 10h
MOV AH, 09h
MOV DX, OFFSET MSG1 ; DOS prints at the cursor
INT 21h
MSG1 DB "column 40", 13, 10, "$"

In graphics modes the position is kept too and says where the BIOS draws its next character (functions 09h, 0Ah, 0Eh, 13h), even though no cursor is shown.

Pitfalls

The BIOS checks nothing. A position off the screen, such as row 25 or column 80, is stored as given: the hardware cursor disappears, and the next character written there lands in memory past the visible area, or in the next page. Some programs park the cursor off the screen to hide it, but INT 10h AH=01h with CH = 20h is the clean way. Moving the cursor of a page that is not shown does not move the one you see.