这是将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
在上面的代码中:
mov [res], al
而不使用mov res, al
?mov ecx,res
而不使用mov ecx,[res]
?****更新
我知道一个是地址,另一个是价值,但我不知道为什么......
答案 0 :(得分:2)
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 请注意,地址和值之间的区别纯粹是语义上的,在汇编中没有这样的划分。