mov指令操作数类型

mov instruction operands type

这是执行 2 和 3 相乘的代码的一部分:

section .text
global _start
_start:
mov al,'3'
sub al, '0'
mov bl, '2'
sub bl, '0'
mul bl
add al, '0'
;first question -> 
mov [res], al
mov ecx,msg
mov edx, len
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80
;second question ->
mov ecx,res
mov edx, 1
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80
mov eax,1 ;system call number (sys_exit)
int 0x80
section .data
msg db "The result is:", 0xA,0xD
len equ $- msg
segment .bss
res resb 1

在上面的代码中:

  1. 为什么要用mov [res], al而不用mov res, al
  2. 为什么要用mov ecx,res而不用mov ecx,[res]

****更新

我知道一个是地址,另一个是那个的值,但我不知道为什么...

res是汇编程序的名称,无非是表示一个值的符号。
你已经知道res的值是它后面第一个字节的地址。
我们通俗地说,res就是变量res.

的地址

在这种情况下,指令 mov res, ecx 没有意义,脱糖后它等同于 mov <a number>, ecx
一个具体的例子:mov 0x12345678, ecx - 进入立即数是没有意义的。

mov ecx, res 是有道理的,它用 res.
的地址加载 ecx 我们需要它的地址而不是它的值,因为 sys_write 将字节流写入文件(stdout 在你的情况下) - 它与打印数字的函数完全不同高级语言。
其实乘法的个位数的结果是通过add al, '0'.
的方式转换成字符串的 转换后sys_write用于将字符串(不是数字!)写入stdout.
由于 sys_write 处理字节流,它希望在 ecx 中写入第一个字节的地址。
您可以查看 C wrapper 来检查参数的类型:const void* 表示第二个参数。
因此必须给出地址 (mov ecx, res) 而不是值 1 (mov ecx, [res])。


1注意地址和值之间的区别纯粹是语义上的,汇编中没有这样的划分。