Compilation – What is the difference between MOV and LEA in terms of retrieval address?

When I use them to get addresses, what is the difference between mov and lea?

Suppose I have a program to print a string starting from the 5th character, the code is as follows:

section .text 
global _start
_start:
mov edx, 0x06 ;the length of msg from its 5th char to the last is 6.
lea ecx, [msg + 4]
mov ebx, 1
mov eax, 4
int 0x80

section .data
msg db '1234567890'

Then if I Swap lea ecx,[msg 4] to mov ecx,msg 4. Will it behave differently?

I tried both and the output looks the same. However, I read from this link, What’s the purpose of the LEA instruction?, in the comment section of the first answer, and it seems someone claims Something like mov ecx, msg 4 is invalid, but I don’t see it. Can someone help me understand this? Thanks in advance!

When the absolute address is the link time constant, mov r32, imm32 and lea r32, [addr] Will get the job done. imm32 can be any valid NASM expression. In this case, msg 4 is the link time constant. The linker will find the final address of msg and add 4 to it (because of the placeholder in .o The character has 4 as a displacement). When the byte is copied from .o to the linker output, this final value will replace the 4B placeholder.

The 4B displacement happens to occur in the effective address of lea The same thing.

The encoding of mov is slightly shorter, can run on more execution ports. Use mov, unless you can use lea to perform some useful mathematical operations on registers at the same time. (For example: lea ecx,[ msg 4 eax * 4 edx])

In 64-bit mode, RIP relative addressing can be performed, and effective position-independent code can be created by using LEA (if it is mapped to a different virtual address, no modification is required) This function cannot be achieved using mov. See Referencing the contents of a memory location. (x86 addressing modes)

For many good links, please refer to the x86 tag wiki.

Please also Note that you can use symbolic constants as the size. You can also format and comment your code better. (The indented operands look less confusing in the code, which have some instructions with longer mnemonics ).

section .text
global _start
_start:
mov edx, msgsize-4
mov ecx, msg + 4; In MASM syntax, this would be mov ecx, OFFSET msg + 4
mov ebx, 1; stdout
mov eax, 4; NR_write
int 0x80; write(1, msg+4 , msgsize-4)

mov eax, 1; NR_exit
xor ecx, ecx
int 0x80; exit(0)
;; otherwise execution falls through into non-code and segfaults

section. rodata
msg db '1234567890'; note, not null-terminated, and no newline
msgsize equ $-msg; current position-start of message

< p>When I use them to get addresses, what is the difference between mov and lea?

Suppose I have a program to print a string starting from the 5th character, the code is as follows:

section .text 
global _start
_start:
mov edx, 0x06 ;the length of msg from its 5th char to the last is 6.
lea ecx, [msg + 4]
mov ebx, 1
mov eax, 4
int 0x80

section .data
msg db '1234567890'

Then if I Swap lea ecx,[msg 4] to mov ecx,msg 4. Will it behave differently?

I tried both and the output looks the same. However, I read from this link, What’s the purpose of the LEA instruction?, in the comment section of the first answer, and it seems someone claims Something like mov ecx, msg 4 is invalid, but I don’t see it. Can someone help me understand this? Thanks in advance!

When the absolute address is the link time constant, mov r32, imm32 and lea r32, [addr] will all complete the work. imm32 can be any valid NASM Expression. In this case, msg 4 is the link time constant. The linker will find the final address of msg and add 4 to it (because the placeholder in .o has 4 as a displacement). Change the byte from. o When copied to the linker output, this final value will replace the 4B placeholder.

The same thing happens to the 4B displacement in the effective address of lea.

The code of mov is slightly shorter, can run on more execution ports. Use mov, unless you can use lea to perform some useful mathematical operations on registers at the same time. (For example: lea ecx,[msg 4 eax * 4 edx])

In 64-bit mode, RIP relative addressing can be performed, and effective position-independent code can be created by using LEA (if it is mapped to a different virtual address, no modification is required). This function cannot be achieved using mov. See Referencing the contents of a memory location. (x86 addressing modes)

For many good links, please refer to the x86 tag wiki.

Please also note that you can use symbolic constants as the size. You can also Your code can be better formatted and commented. (The indentation operands look less confusing in the code, these codes have some instructions with longer mnemonics).

section .text
global _start
_start:
mov edx, msgsize-4
mov ecx, msg + 4; In MASM syntax, this would be mov ecx, OFFSET msg + 4
mov ebx, 1; stdout
mov eax, 4; NR_write
int 0x80; write(1, msg+4, msgsize-4)

mov eax, 1; NR_exit
xor ecx, ecx
int 0x80; exit(0)
;; otherwise execution falls through into non-code and segfaults

section .rodata
msg db '1234567890'; note, not null-terminated , and no newline
msgsize equ $-msg; current position-start of message

Leave a Comment

Your email address will not be published.