我正在使用以下代码:
section .text
global _start
_start:
mov ebx, testing
mov [ebx], byte 0x4A
add ebx, byte 1
mov [ebx], byte 0x4B
add ebx, byte 1
mov [ebx], byte 0x4C
;sets var1 as '*'
mov eax, 0x2A
mov [var1], eax
;sets var2 as 'N'
mov eax, 0x4E
mov [var2], eax
;sets var3 = var2
mov eax, [var2]
mov [var3], eax
;Prints var1
mov eax, 4
mov ebx, 1
mov ecx, var1
mov edx, 1
int 0x80
;Jumps a line
mov eax, 4
mov ebx, 1
mov ecx, line_break
mov edx, 2
int 0x80
;Prints var2
mov eax, 4
mov ebx, 1
mov ecx, var2
mov edx, 1
int 0x80
;Jumps a line
mov eax, 4
mov ebx, 1
mov ecx, line_break
mov edx, 2
int 0x80
;Prints var3
mov eax, 4
mov ebx, 1
mov ecx, var3
mov edx, 1
int 0x80
;Jumps a line
mov eax, 4
mov ebx, 1
mov ecx, line_break
mov edx, 2
int 0x80
;Prints variable
mov eax, 4
mov ebx, 1
mov ecx, variable
mov edx, 3
int 0x80
;Jumps a line
mov eax, 4
mov ebx, 1
mov ecx, line_break
mov edx, 2
int 0x80
;Prints testing
mov eax, 4
mov ebx, 1
mov ecx, testing
mov edx, 3
int 0x80
;Jumps a line
mov eax, 4
mov ebx, 1
mov ecx, line_break
mov edx, 2
int 0x80
;Finishes program
mov eax, 1
mov ebx, 1
int 0x80
section .data
variable times 3 db 0x2A
line_break dw 0x0D0A
section .bss
testing resb 3
var1 resb 1
var2 resb 1
var3 resb 1
打印出来:
*
N
N
***
JKL
我不明白的是:为什么在第一行“mov ebx,testing”中没有括号arround“testing”以及为什么这些括号出现在[var2]行“mov eax,[var2]中”。这种符号究竟是如何工作的? [var2]不应该是var2的有效地址吗?
答案 0 :(得分:1)
标识符周围的括号表示该值应用作指针。所以没有括号:
mov ebx, testing
将testing
的地址移到eax
寄存器中,其中
mov eax, [var2]
将var2指向的值移动到eax
。
答案 1 :(得分:0)
为什么在第一行“mov ebx,testing”中没有括号“测试”
您问题中的代码是用NASM语法编写的。还有其他x86汇编器使用稍微不同的语法(例如MASM和TASM)。
无论如何,mov ebx, testing
表示“将testing
的地址放在注册ebx
”中。然后在下一行使用该地址,其中指令mov [ebx], byte 0x4A
将值0x4A
写入ebx
指向的第一个字节(即testing
处的第一个字节)。
在MASM / TASM语法中,您可以将其写为mov ebx, OFFSET testing
。
为什么这些括号出现在[var 2]行“mov eax,[var2]”
中
因为您希望获得var2
的值,而不是var2
的地址。在NASM语法中,您可以使用括号来完成此操作,如mov eax,[var2]
中所示。在MASM / TASM语法中,mov eax,[var2]
和mov eax,var2
都会读取var2
处的值。
请注意,var1
,var2
和var3
各占一个字节。因此,尝试从/向这些变量读取和写入32位寄存器看起来像一个错误。您可能希望将声明从resb 1
更改为resd 1
,或者只是从/向它们读取/写入8位寄存器。