In this assembly instruction
mov ax, es:[bx]
what does the :
do?
In this assembly instruction
mov ax, es:[bx]
what does the :
do?
what specifically does the : do?
The ":" doesn't "do" anything, in the same way that "." doesn't "do" anything in most high level programming languages. A ':' is used with an instruction of the form <segment register> : <address expression>
. By default, all x86 instructions have a "default segment selector" which is used to determine the address indicated by an instruction's "memory operand". This is usually either "ds" or "ss", depending on the instruction. An instruction may specify any of the CS,DS,ES,SS, FS, and GS segment registers, however, by specifying an appropriate "instruction prefix byte" in the instructions binary encoding.
In 16 bit "real mode" programs the value in a segment register is used to determine the "higher order bits" of a memory address. It get's combined with the memory address specified in the instruction to generate the actual address referenced by the instruction. This allowed programs running on 16 bit hardware to have access to larger than 16 bit memory spaces, provided they could group memory into 4k chunks that could be accessed relative to a "segment selector" register.
In 32 bit programs the segment selector is actually an index into a structure that describes a dynamic mapping, including an offset and a size. The address is computed by combining the information present in the indexed structure with the memory operand present in the instruction.
Most of the time, in 32 bit programs, most segment registers point to structures that specify the entire 32 bit address space. The primary exception is the "fs" register, which specifies an offset and size that maps to a special data structure defined by the operating system. It is used as one of the mechanisms for communication between kernel space and user space. It usually contains access to all the "user space visible" attributes of the Kernel's representation of the current "process or thread".
64 bit programs completely eschew segment registers. All segment registers except FS and GS are defined to have no effect, and behave as if they mapped the entire user space. The FS register is usually used to provide access to the current "32 bit context" of the executing program. The "GS" register is usually used to provide access to the current "64 bit context". This allows 32 bit programs to run on 64 bit systems, but also gives the 64 bit kernel (and the mapping layer between 32 bit process and 64 bit processes) access to the 64 bit context it needs to work.
So, to answer your original question:
Probabilisticly (given no knowledge about the mode of the processor or the operating system), the instruction:
mov ax, es:[bx]
is actually equivalent to:
mov ax, [bx]
However, the fact that it uses 16 bit registers indicates that it might be a real mode program, in which case it may mean:
mov ax, [<addr>]
where addr == (es << 4) + [bx]
mov ax, es:[bx]
and mov ax, [bx]
are not equivalent, unless an assume
command was used before. The default register in this case would be ds
not es
, so the segment o verride is needed, which is what the es:
does. –
Tradesman ds
and es
having the same value. So in Windows programs the effect of the instructions are the same, because es
and ds
points to the same segment, but that doesn't make the instruction itself equivalent, only the effect of it in a Windows system (maybe also in Linux? Since the OP apparently doesn't know this, he would be misleaded. You should replace the probabillity
part with assuming es and ds are equal
. –
Tradesman ds
was expected to be equal to es
, the code would have used just [bx]
, because the default segment for [bx]
is DS, not ES. Using es
requires a segment override prefix (one extra byte of code size). The fact that they went out of their way to use ES means it's highly likely not equivalent. –
Coalfield :
is convention to indicate the segment portion of an address. ES
therefore is a segment (hence SI
for instance in this position would be invalid) and [BX]
the offset within that segment; a segment register used as an offset would equally be invalid and generte an error.
When you access some data in your process memory, then there is always a segment register involved, which defines a memory window with the main register as the offset. These registers are cs
, ds
, es
, ss
, fs
and gs
. Some of these segment registers have a special purpose like the cs
(code segment) or the ss
(stack segment).
When you access data with a register like in your example then a default segment is selected by the assembler. This segment register is encoded in the instruction.
There are cases when you want to override the default selection, and use a different segment register, than the default one, and you can achieve this by using a segment override which is what your example is doing.
When executing
mov eax, [ebx]
by default the ds
segment would be used
but the instruction with the segment override
mov eax, es:[ebx]
specifies that the es
segment should be used instead. In Windows, by default, ds
and es
point to the same segment, so this override wouldn't be needed, as it will access the same linear and physical address.
DS:OFFSET where DS is the segment address and ,OFFSET is the offset relative to the segment.
it means compute the address like this way :DS * size_of_segment + OFFSET
normally, for x86 the size of segment is 16byte.
For example:
DS: 07C0H 0000 0111 1100 0000
+ OFFSET: 0000H 0000 0000 0000 0000
= 07C00H 0000 0111 1100 0000 0000
DS*16 + OFFSET
. In real mode, the size of a segment is fixed at 64kiB. The distance between adjacent segment bases is 16 bytes, but that's not the size. –
Coalfield © 2022 - 2024 — McMap. All rights reserved.