x86 asm 的 NASM 语法中的括号意味着什么?
给出以下代码:
L1 db "word", 0
mov al, [L1]
mov eax, L1
[L1]
中的括号代表什么?
这个问题专门针对 NASM。 Intel 语法汇编的另一个主要风格是 MASM 风格,当不涉及寄存器时,括号的工作方式有所不同:
请参阅 MASM32 中令人困惑的括号
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
[L1]
表示地址L1处的存储器内容。在此处运行mov al, [L1]
后,al
寄存器将接收地址 L1 处的字节(字母“w”)。[L1]
means the memory contents at address L1. After runningmov al, [L1]
here, Theal
register will receive the byte at address L1 (the letter 'w').这种类型的操作数,例如
[ebp]
,称为 内存操作数。这里的所有答案都很好,但我发现没有一个答案说明了遵循这一严格规则的警告 - 如果括号,则取消引用,除非它是
lea指令
。
lea
是上述规则的一个例外。假设我们将ebp
的值减去 4,括号表示将所得值作为地址,并将驻留在该地址的值存储在eax
中。但是,在lea
的情况下,括号并不意味着:ebp
的值减去 4,结果值存储在eax< /代码>。该指令仅计算地址并将计算出的值存储在目标寄存器中。请参阅MOV 和 LEA 有什么区别? 了解更多详情。
Operands of this type, such as
[ebp]
, are called memory operands.All the answers here are good, but I see that none tells about the caveat in following this as a rigid rule - if brackets, then dereference, except when it's the
lea
instruction.lea
is an exception to the above rule. Say we'veThe value of
ebp
is subtracted by 4 and the brackets indicate that the resulting value is taken as an address and the value residing at that address is stored ineax
. However, inlea
's case, the brackets wouldn't mean that:The value of
ebp
is subtracted by 4 and the resulting value is stored ineax
. This instruction would just calculate the address and store the calculated value in the destination register. See What is the difference between MOV and LEA? for further details.简单来说就是获取标签L1所标记地址处的内存。
如果您喜欢 C,那么可以这样想:
[L1]
与*L1
相同Simply means to get the memory at the address marked by the label L1.
If you like C, then think of it like this:
[L1]
is the same as*L1
括号的意思是取消引用地址。例如
表示将地址1234的内容mov到EAX。所以:
EAX 将包含 00001。
The brackets mean to de-reference an address. For example
means, mov the contents of address 1234 to EAX. So:
EAX will contain 00001.
直接内存寻址 -
al
将加载位于内存地址L1
的值。Direct memory addressing -
al
will be loaded with the value located at memory addressL1
.与许多汇编语言一样,这意味着间接。换句话说,第一个
mov
加载al
以及L1
的内容(字节'w '
换句话说),而不是地址。您的第二个
mov
实际上使用地址L1
加载eax
,您可以稍后取消引用它以获取或设置其内容。在这两种情况下,
L1
在概念上都被视为地址。As with many assembler languages, this means indirection. In other words, the first
mov
loadsal
with the contents ofL1
(the byte'w'
in other words), not the address.Your second
mov
actually loadseax
with the addressL1
and you can later dereference that to get or set its content.In both those cases,
L1
is conceptually considered to be the address.它们的意思是,不要将寄存器的值或数值
L1
移动到寄存器al
中,而是将寄存器值或数值L1
视为指向内存的指针,获取该内存地址的内容,并将该内容移至al
中。在本例中,L1 是一个内存位置,但如果寄存器名称位于括号中,则将应用相同的逻辑:
也称为加载。
They mean that instead of moving the value of the register or numeric value
L1
into the registeral
, treat the register value or numeric valueL1
as a pointer into memory, fetch the contents of that memory address, and move that contents intoal
.In this instance, L1 is a memory location, but the same logic would apply if a register name was in the brackets:
Also known as a load.
在 MASM 中,与寄存器一起使用时,括号的工作方式与 NASM 类似,在这种情况下,括号不是可选的。 (对于不涉及寄存器的寻址模式,情况有所不同,请参阅 MASM32 中令人困惑的括号 )
括号表示寄存器包含一个指针,并且机器代码需要该指针的值(指针采用字节寻址:指针是内存的第 x 个字节;一个字节是 8 个二进制数字;一个十六进制数字是4个二进制数字;作为一个字节是从那里开始的2个十六进制数字);如果它位于指令的 src 部分。
在二进制机器代码中,(在 notepad.exe 中键入十六进制数字,然后将十六进制数字转换为 \xhexadecimal result~python_reference)以获得寄存器中指针的值,它可以在将要写入 notepad.exe 的指令的 ModR/M 字节中定义,我认为它有 10 个字符。 (我首先完成了我的 MASM 体验,然后我将继续通过阅读 Windows 的内核/恶意软件分析来清理有关在 notepad.exe 中输入什么内容的信息;我将回到这篇文章并写一个示例)
Windows:
如果您输入执行此操作的结果并进行比较:
程序的退出状态(使用
echo
打印)将是存储到堆栈内存中的数字,并以mov [esp], al
作为参数ExitProcess,以十六进制 FF 结尾。 (%ERRORLEVEL%
将数字转换为十进制数字字符串,而不是十六进制,但它是相同的数字。)但是,如果没有
[esp 周围的 [] ]
:我们还必须将 AL 更改为 EAX(因为 x86 CPU 没有将 8 位寄存器移动到 32 位寄存器底部的指令)。并删除代码行中最后一次使用字母“esp”周围的括号;它将导致指向 esp 中堆栈区域的指针。标签:可选括号
上面的代码证明了括号在将机器代码解释为可读方式而不是字节的语言中始终有效(使用代码中的值作为指针并获取指针的值)知道 Windows 内核如何执行 exe 文件(对 Windows 内核进行逆向工程,以便在记事本内从头开始制作自己的 exe 文件,这没有足够的支持;但是,恶意软件分析确实有足够的支持。)
(如果您想测试代码:将最后代码中的行替换为 testfunc,并以与行相同的方式执行它):在这种情况下,eax 等于堆栈段内存中 esp 的指针(堆栈段很重要,因为它有它自己的指令:从/到立即数、寄存器或内存操作数的 PUSH 和 POP 32 位值)。因此,当您执行它时,裸露的 esp 操作数是 ESP 寄存器的值,一个指针值,而不是堆栈上的内存内容。
我会偶尔回来编辑这篇文章(如果我真的很擅长组装的话);因此,这可以成为组装的终极指南。我刚刚开始进行汇编,并在汇编中的特定范围脚本中快速生成最高有效位查找器的长度。
到目前为止帮助我制作这个脚本的资源:
整个 C++ 的 5 小时教程:
我建议在此之后进行一次寻宝游戏,学习 HTML/CSS/JS 并制作一个计算器网站(将 html 文件拖放到 Microsoft Edge),以及对像 Undertale 这样的视频游戏进行编码(拖放 html)文件到 Microsoft Edge),然后学习 Python3 只是为了开玩笑。
帮助我找出 DWORD 之类的东西是什么(无符号长整型)。
https://www.bing.com
我读到了第三卷的一半,然后浏览了剩下的
https://www.intel。 com/content/www/us/en/developer/articles/technical/intel-sdm.html
Davy Wybrial 的汇编语言教程值得一看:
https://www.youtube.com/watch?v=wLXIWKUWpSs&ab_channel=戴维维比拉尔
英特尔软件开发人员手册的“操作部分”部分:
如何在 Windows 上开始编写汇编代码 (MASM)
https://www.youtube.com/watch?v=lCjbwLeLNfs&ab_channel= CharlesClayton
再次,我将回到这里(这篇文章以及我未来的文章)并尝试教育每个人,以便我的知识与每个阅读的人相同。
In MASM, brackets work like NASM when used with registers, and in that case are not optional. (Things are different for addressing modes that don't involve a register, see Confusing brackets in MASM32)
The brackets indicate that the register contains a pointer, and that the machine code wants the value of that pointer (pointers are in byte-addressing: a pointer is the xth byte of memory; a byte is 8 binary digits; one hexadecimal digit is 4 binary digits; as a byte is 2 hexadecimal digits; starting from there); if it's in the src part of the instruction.
In binary machine code, (typing hexadecimal digits in notepad.exe then converting hexadecimal digits into \xhexadecimal result~python_reference) to get the value of a pointer in a register, it can be defined in the ModR/M byte of the instruction that's going to be written in notepad.exe which is 10 characters I believe. (I'm finishing my MASM experience first, then I'm going to move on to scavenge information about what to type into notepad.exe through readings of window's kernel/malware analysis; I'll come back to this post and write up an example)
Windows:
If you would type the result of executing this, and compare:
The program's exit status (printed with
echo
) would be a the number stored to stack memory withmov [esp], al
as the arg to ExitProcess, ending in hex FF. (%ERRORLEVEL%
converts the number to a string of decimal digits, not hex, but it's the same number.)However, without the [] around
[esp]
: we also have to change AL to EAX (because x86 CPUs don't have an instruction to move 8-bit registers to bottom of 32-bit registers). And remove the brackets around the last time the letters 'esp' was used in the lines of code; it would result in the pointer to the stack region in esp.Tag: optional brackets
The above code is proof that the brackets ALWAYS WORK (uses the value inside whatever the code is as a pointer and gets the value of the pointer) in language interpreting machine code into a readable way instead of bytes and knowing how the Windows kernel would execute an exe file (reverse engineer window's kernel to make your own exe files from scratch inside notepad, which there isn't enough support in; however, malware analysis does have enough support.)
(If you want to test the code: you replace the lines with the testfunc in last code, and execute it the same way with the lines): In this case, eax is equal to esp's pointer in memory of the stack segment (stack segment is important because it has its own instructions: PUSH and POP 32-bit values from / to an immediate, register, or memory operand). So when you execute it, the bare
esp
operand is the value of the ESP register, a pointer value, not memory contents on the stack.I'll come back and edit this post once in a while (if I actually get really good at assembly.); So, this can be an ultimate guide to assembly. I just got started in assembly and making a quick length of the most significant bit finder in a specific range script in assembly.
Resources that have helped me gotten to make this script so far:
5 hour tutorial of the entirety of C++:
I recommend after this doing a scavenger hunt of learning HTML/CSS/JS and making a calculator website (a drag and drop of html file to Microsoft Edge), and scavenger hunt of coding a video game like Undertale (a drag and drop of html file to Microsoft Edge), and then learn Python3 just for jokes.
Helps me find out what stuff like DWORDs are (unsigned long).
https://www.bing.com
I read till half of Volume 3 and then skimmed the rest
https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html
Davy Wybrial's assembly language tutorial to watch after all that of watching:
https://www.youtube.com/watch?v=wLXIWKUWpSs&ab_channel=DavyWybiral
The Intel Software Developer Manual's section called 'Operation Section':
How to Start Coding Assembly on Windows (MASM)
https://www.youtube.com/watch?v=lCjbwLeLNfs&ab_channel=CharlesClayton
Again, I'll come back to here (this post, and as well as my future posts) and try to educate everyone, so my knowledge is equal with everyone reading.
它表明寄存器应该用作实际位置的指针,而不是作用于寄存器本身。
It indicates that the register should be used as a pointer for the actual location, instead of acting upon the register itself.