常用 x86 汇编指令,以及其含义

# Move

move 操作对象可以是
寄存器 <- 寄存器
寄存器 <- 内存
寄存器 <- 立即数
内存 <- 寄存器
内存 <- 立即数

立即数可以看成 C 语言里的常数 (大概吧)

是进行数据操作的指令

# Lea

加载有效地址到寄存器。
加载地址也可以用 mov 指令,但是在有些情况下 lea 会很简便

# 关于符号 []

对于操作数,经常可以看到 []。
我总是很困惑这个符号,因为它有时候表示解引用,操作的是内存的值,有时候又是表示地址。现在来梳理一下吧。

例子1
mov     eax, [eax+18h]
 lea     edx, [eax+28h]

关于上面的汇编,未执行前 eax 里装的是数组的首地址。mov 第二操作数是数组里的元素,而 lea 的第二操作数是一个地址。同样的一个 [],在 mov 为解引用,在 lea 却只是一个简单的加法运算。

例子2
MOV EBX, [MY_TABLE]     ; Effective Address of MY_TABLE in EBX
MOV [EBX], 110          ; MY_TABLE[0] = 110
ADD EBX, 2              ; EBX = EBX +2
MOV [EBX], 123

这个例子来自 w3school 寻址模式
按照注释理解,[MY_TABLE] 是一个数组地址,
[EBX] 却是解引用。
查找了一下资料,这里进行一下梳理吧 (不知道对不对,欢迎指正)。

# 对于 lea: 装入有效地址的指令

  • 第一个操作数一定是寄存器
  • 第二个操作数可以是寄存器,变量,地址表达式

重点在第二个操作数

  • 第二个操作数为变量时
    因为是进行地址加载的指令,[] 加不加都没关系,解释为 DS: 变量偏移,这时的变量都是解释为地址 (也就是变量偏移), 不会取变量的值

  • 第二个操作数为寄存器或者地址表达式时
    必须要加 [] , 因为 lea 是加载地址的第二个操作数一定是地址,也就是 DS: 寄存器的值,这里的 [] 就是取寄存器的值,并没有解引用 (地址表达式也是表达式的值,并没有引用地址数据)。

# 对于 mov: 进行数据操作的指令

两个操作数的类型是不固定的,我们假设操作数第一个是个寄存器。

  • 第二个操作数为变量时

因为是进行数据操作的指令,不管变量加不加 [] 都是相同的效果,都是解引用,获取变量的数据到寄存器。栗子 2 的第一条代码就明白了,[] 是不用管的。

  • 第二个操作数为寄存器或者地址表达式

第二个操作数是寄存器的时候,就是我们常见的情况了,加 [] 是把寄存器里的地址数据取出来解引用得到地址里的数据,把地址里的数据装入寄存器。不加 [] 是直接装寄存器的数据,不管数据是一个地址还是其他什么东西。

第二个操作数是地址表达式一定要加 [] ,这个可以理解 (你找不到不加 [] 的地址表达式), 这时是解引用,把数据装入寄存器。你可能要问了,如果我想把地址表达的值装入寄存器呢?我们有两种方法

  • 方法一:使用 lea 指令 (也就是 lea 的第二种情况)。
  • 方法二:先用 add 之类的指令把地址表达式的值算出来,然后值给到第二次操作数的寄存器 ebx, 再执行 mov eax, ebx

# 总结

对于汇编指令来说 [] 只是一个标记,并没有特定的含义,具体含义应该看其所在的对应指令。除了上面的两个指令使用 [] 外,在编写汇编代码时,甚至可以用 变量[] 来使用数组元素 (有点像 c 语言了), 当然在 ida 几乎看不到这样的东西,这只是一个语法糖。把 mov 和 lea 理解透了才能清楚汇编执行时倒是操作的是地址还是数据。

阅读次数

请我喝[茶]~( ̄▽ ̄)~*

PangBai 微信支付

微信支付

PangBai 支付宝

支付宝

PangBai 贝宝

贝宝