Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how does LEA and several instruction work? [duplicate]

Tags:

x86

assembly

I dont fully understand the meaning of first two lines, and the difference of last two lines..

LDS SI,[BX]
LES DI,[BX]
LEA DI,5000h 
MOV DI,5000h

I think LEA loads 5000h in DI and MOV loads content of 5000h in DI. Am I right??

like image 703
Wahid Masud Avatar asked Dec 21 '22 01:12

Wahid Masud


2 Answers

The first two load the contents of 32 bits pointed to by bx into ds and si (or es and di).

The second two are the same because the values are literals. If, however they were:

lea di,[bx]
mov di,[bx]

then your expectation would be right: the former putting the address bx into di and the latter putting the 16 bits pointed to by bx into di.

For more information on both, see this question for les/lds and this question for mov/lea.

like image 71
DocMax Avatar answered Dec 26 '22 11:12

DocMax


The lea instruction doesn't actually load anything from memory.

In 8086, the capabilities of lea were limited, comparing to what we have now. lea just can make a sum of up to two address registers and an immediate (constant) value, and put this sum to a destination register. For example, lea bp, [bx+si+3] sets to the bp register the sum of bx plus si plus 3.

The 80386 processor introduced a series of scaling modes, in which the index register value can be multiplied by a valid scaling factor to obtain the displacement. The valid scale factors are 1, 2, 4, and 8. Therefore, you can use instructions like lea ebp, [ebx+esi*8+3].

The instructions lds and les, on the contrary, load values from memory to a pair of registers: one segment register (ds or es) and one general register. There are also versions of this load instruction for the other segment registers: lfs, lgs and lss for fs, gs and ss segment registers respectively (introduced in 80386). So these instructions load "far" pointer - a pointer consisting of a 16-bit segment selector and a 16-bit (or a 32-bit, depending on mode) offset, so the total far pointer size was 32-bit in 16-bit mode and 48-bit in 32-bit mode.

These are handy instructions for 16-bit mode, be it 16-bit real mode or 16-bit protected mode.

Under 32-bit mode, there is no need for these instructions since OSes set all segment bases to zero (flat memory model), so there is no need to load segment registers. We just use 32-bit pointers, not 48.

Under 64-bit modes, these instructions are not implemented. Their opcodes give access violation interrupt (exception). Since Intel's implementation of VEX - "vector extensions - (AVX), Intel reclaimed the opcodes of lds and les and started using them for VEX prefixes. That is why only x/ymm0..7 are accessible in 32-bit mode. The VEX prefixes overlap with invalid encodings of lds and les in 32-bit mode, where R̅, X̅, and B̅ bits are all 1.

like image 37
Maxim Masiutin Avatar answered Dec 26 '22 10:12

Maxim Masiutin