Copyright (C) 2000-2012 |
GNU Info (nasm.info)Section 9.29.2. Addressing Between Different-Size Segments =============================================== If your OS is mixed 16 and 32-bit, or if you are writing a DOS extender, you are likely to have to deal with some 16-bit segments and some 32-bit ones. At some point, you will probably end up writing code in a 16-bit segment which has to access data in a 32-bit segment, or vice versa. If the data you are trying to access in a 32-bit segment lies within the first 64K of the segment, you may be able to get away with using an ordinary 16-bit addressing operation for the purpose; but sooner or later, you will want to do 32-bit addressing from 16-bit mode. The easiest way to do this is to make sure you use a register for the address, since any effective address containing a 32-bit register is forced to be a 32-bit address. So you can do mov eax,offset_into_32_bit_segment_specified_by_fs mov dword [fs:eax],0x11223344 This is fine, but slightly cumbersome (since it wastes an instruction and a register) if you already know the precise offset you are aiming at. The x86 architecture does allow 32-bit effective addresses to specify nothing but a 4-byte offset, so why shouldn't NASM be able to generate the best instruction for the purpose? It can. As in *Note Section 9.1::, you need only prefix the address with the `DWORD' keyword, and it will be forced to be a 32-bit address: mov dword [fs:dword my_offset],0x11223344 Also as in *Note Section 9.1::, NASM is not fussy about whether the `DWORD' prefix comes before or after the segment override, so arguably a nicer-looking way to code the above instruction is mov dword [dword fs:my_offset],0x11223344 Don't confuse the `DWORD' prefix _outside_ the square brackets, which controls the size of the data stored at the address, with the one `inside' the square brackets which controls the length of the address itself. The two can quite easily be different: mov word [dword 0x12345678],0x9ABC This moves 16 bits of data to an address specified by a 32-bit offset. You can also specify `WORD' or `DWORD' prefixes along with the `FAR' prefix to indirect far jumps or calls. For example: call dword far [fs:word 0x4321] This instruction contains an address specified by a 16-bit offset; it loads a 48-bit far pointer from that (16-bit segment and 32-bit offset), and calls that address. automatically generated by info2www version 1.2.2.9 |