x86 asm 的 NASM 语法中的括号意味着什么?

发布于 2024-08-17 23:31:25 字数 330 浏览 1 评论 0 原文

给出以下代码:

L1     db    "word", 0

       mov   al, [L1]
       mov   eax, L1

[L1]中的括号代表什么?


这个问题专门针对 NASM。 Intel 语法汇编的另一个主要风格是 MASM 风格,当不涉及寄存器时,括号的工作方式有所不同:
请参阅 MASM32 中令人困惑的括号

Given the following code:

L1     db    "word", 0

       mov   al, [L1]
       mov   eax, L1

What do the brackets in [L1] represent?


This question is specifically about NASM. The other major flavour of Intel-syntax assembly is MASM style, where brackets work differently when there's no register involved:
See Confusing brackets in MASM32

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

凉栀 2024-08-24 23:31:25

[L1]表示地址L1处的存储器内容。在此处运行 mov al, [L1] 后,al 寄存器将接收地址 L1 处的字节(字母“w”)。

[L1] means the memory contents at address L1. After running mov al, [L1] here, The al register will receive the byte at address L1 (the letter 'w').

有深☉意 2024-08-24 23:31:25

这种类型的操作数,例如 [ebp],称为 内存操作数

这里的所有答案都很好,但我发现没有一个答案说明了遵循这一严格规则的警告 - 如果括号,则取消引用除非它是lea指令

lea 是上述规则的一个例外。假设我们将

mov eax, [ebp - 4]

ebp 的值减去 4,括号表示将所得值作为地址,并将驻留在该地址的值存储在 eax 中。但是,在 lea 的情况下,括号并不意味着:

lea eax, [ebp - 4]

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've

mov eax, [ebp - 4]

The 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 in eax. However, in lea's case, the brackets wouldn't mean that:

lea eax, [ebp - 4]

The value of ebp is subtracted by 4 and the resulting value is stored in eax. 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.

请持续率性 2024-08-24 23:31:25

简单来说就是获取标签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

丢了幸福的猪 2024-08-24 23:31:25

括号的意思是取消引用地址。例如

mov eax, [1234]

表示将地址1234的内容mov到EAX。所以:

1234 00001

EAX 将包含 00001。

The brackets mean to de-reference an address. For example

mov eax, [1234]

means, mov the contents of address 1234 to EAX. So:

1234 00001

EAX will contain 00001.

海未深 2024-08-24 23:31:25

直接内存寻址 - al 将加载位于内存地址L1的值。

Direct memory addressing - al will be loaded with the value located at memory address L1.

写给空气的情书 2024-08-24 23:31:25

与许多汇编语言一样,这意味着间接。换句话说,第一个 mov 加载 al 以及 L1内容(字节 'w ' 换句话说),而不是地址。

您的第二个mov实际上使用地址L1加载eax,您可以稍后取消引用它以获取或设置其内容。

在这两种情况下,L1 在概念上都被视为地址。

As with many assembler languages, this means indirection. In other words, the first mov loads al with the contents of L1 (the byte 'w' in other words), not the address.

Your second mov actually loads eax with the address L1 and you can later dereference that to get or set its content.

In both those cases, L1 is conceptually considered to be the address.

混浊又暗下来 2024-08-24 23:31:25

它们的意思是,不要将寄存器的值或数值 L1 移动到寄存器 al 中,而是将寄存器值或数值 L1 视为指向内存的指针,获取该内存地址的内容,并将该内容移至 al 中。

在本例中,L1 是一个内存位置,但如果寄存器名称位于括号中,则将应用相同的逻辑:

mov al, [ebx]

也称为加载。

They mean that instead of moving the value of the register or numeric value L1 into the register al, treat the register value or numeric value L1 as a pointer into memory, fetch the contents of that memory address, and move that contents into al.

In this instance, L1 is a memory location, but the same logic would apply if a register name was in the brackets:

mov al, [ebx]

Also known as a load.

穿越时光隧道 2024-08-24 23:31:25

在 MASM 中,与寄存器一起使用时,括号的工作方式与 NASM 类似,在这种情况下,括号不是可选的。 (对于不涉及寄存器的寻址模式,情况有所不同,请参阅 MASM32 中令人困惑的括号 )

括号表示寄存器包含一个指针,并且机器代码需要该指针的值(指针采用字节寻址:指针是内存的第 x 个字节;一个字节是 8 个二进制数字;一个十六进制数字是4个二进制数字;作为一个字节是从那里开始的2个十六进制数字);如果它位于指令的 src 部分。

  • 但是,如果 dst 有括号:该地址处的内存是该指令的操作数。 (内存就像之前讨论过的“字节寻址”指针一样。)

在二进制机器代码中,(在 notepad.exe 中键入十六进制数字,然后将十六进制数字转换为 \xhexadecimal result~python_reference)以获得寄存器中指针的值,它可以在将要写入 notepad.exe 的指令的 ModR/M 字节中定义,我认为它有 10 个字符。 (我首先完成了我的 MASM 体验,然后我将继续通过阅读 Windows 的内核/恶意软件分析来清理有关在 notepad.exe 中输入什么内容的信息;我将回到这篇文章并写一个示例)

1 .686
2 .model flat, c
3 option casemap :none
4 
5 include C:\masm32\include\kernel32.inc
6 includelib C:\masm32\lib\kernel32.lib
7 
8 .data 
9     message db "Hello world!", 0
10 .code
11 
12 main proc
13  call testfunc
14  COMMENT @ 
15  push 0FFFFh
16  push testfunc
17  pop ax
18  @
19  invoke ExitProcess, 404
20 main ENDP
21 
22 testfunc proc
23  sub esp, 1
24  mov al, 0FFh
25  mov [esp], al
26  COMMENT @
27  push 0FFFFh
28  push 05EFFB880h
29  push 0773BFF5Ch
30  push 0FB038Fh
31  mov al, [esp+8]
32  @
33  invoke ExitProcess, [esp]
34 testfunc ENDP
35 
36 END main

Windows:
如果您输入执行此操作的结果并进行比较:

C:\masm32\bin\ml /c /Zd /coff script_name.asm
C:\masm32\bin\Link /SUBSYSTEM:CONSOLE script_name.obj
脚本名称.exe
回显%ERRORLEVEL%

程序的退出状态(使用 echo 打印)将是存储到堆栈内存中的数字,并以 mov [esp], al 作为参数ExitProcess,以十六进制 FF 结尾。 (%ERRORLEVEL% 将数字转换为十进制数字字符串,而不是十六进制,但它是相同的数字。)

但是,如果没有 [esp 周围的 [] ]:我们还必须将 AL 更改为 EAX(因为 x86 CPU 没有将 8 位寄存器移动到 32 位寄存器底部的指令)。并删除代码行中最后一次使用字母“esp”周围的括号;它将导致指向 esp 中堆栈区域的指针。

1 testfunc proc
2   mov eax, esp
3   mov bl, 0FFh
4   mov [eax], bl
5   COMMENT @
6   push 0FFFFh
7   push 05EFFB880h
8   push 0773BFF5Ch
9   push 0FB038Fh
10  mov al, [esp+8]
11  @
12  invoke ExitProcess, [esp]
13 testfunc ENDP

标签:可选括号

上面的代码证明了括号在将机器代码解释为可读方式而不是字节的语言中始终有效(使用代码中的值作为指针并获取指针的值)知道 Windows 内核如何执行 exe 文件(对 Windows 内核进行逆向工程,以便在记事本内从头开始制作自己的 exe 文件,这没有足够的支持;但是,恶意软件分析确实有足够的支持。)

(如果您想测试代码:将最后代码中的行替换为 testfunc,并以与行相同的方式执行它):在这种情况下,eax 等于堆栈段内存中 esp 的指针(堆栈段很重要,因为它有它自己的指令:从/到立即数、寄存器或内存操作数的 PUSH 和 POP 32 位值)。因此,当您执行它时,裸露的 esp 操作数是 ESP 寄存器的值,一个指针值,而不是堆栈上的内存内容。


我会偶尔回来编辑这篇文章(如果我真的很擅长组装的话);因此,这可以成为组装的终极指南。我刚刚开始进行汇编,并在汇编中的特定范围脚本中快速生成最高有效位查找器的长度。

到目前为止帮助我制作这个脚本的资源:
整个 C++ 的 5 小时教程:

  • https:// www.youtube.com/watch?v=vLnPwxZdW4Y&ab_channel=freeCodeCamp.org

    我建议在此之后进行一次寻宝游戏,学习 HTML/CSS/JS 并制作一个计算器网站(将 html 文件拖放到 Microsoft Edge),以及对像 Undertale 这样的视频游戏进行编码(拖放 html)文件到 Microsoft Edge),然后学习 Python3 只是为了开玩笑。

帮助我找出 DWORD 之类的东西是什么(无符号长整型)。
https://www.bing.com

  • 请阅读英特尔软件开发人员手册,它告诉你一些东西就像如果你改变内存中的一个位置,它被称为高级可编程中断控制器的命令寄存器,它将在另一个核心(CPU)中执行代码。您不必记住,只是我建议将所有内容重写为 txt,然后编写一个脚本来在您创建 txt 的每个新部分中搜索一个单词。我什至没有记住书上的任何内容,我只是知道一些我头脑中的常识部分,我希望你能为读者了解更多。

我读到了第三卷的一半,然后浏览了剩下的
https://www.intel。 com/content/www/us/en/developer/articles/technical/intel-sdm.html

  • 我观看了一些https://www.youtube.com/c/WhatsACreel 视频,因为我正在写一章,并且在阅读之间有 30 天的休息时间,这样我可以更好地理解。我也建议这样做,但我不知道如何告诉您何时停止并质疑您观看视频的想法;对不起。

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.

  • However, if dst has the brackets: memory at that address is an operand for the instruction. (Memory as in pointer of "byte-addressing" talked about, previously.)

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)

1 .686
2 .model flat, c
3 option casemap :none
4 
5 include C:\masm32\include\kernel32.inc
6 includelib C:\masm32\lib\kernel32.lib
7 
8 .data 
9     message db "Hello world!", 0
10 .code
11 
12 main proc
13  call testfunc
14  COMMENT @ 
15  push 0FFFFh
16  push testfunc
17  pop ax
18  @
19  invoke ExitProcess, 404
20 main ENDP
21 
22 testfunc proc
23  sub esp, 1
24  mov al, 0FFh
25  mov [esp], al
26  COMMENT @
27  push 0FFFFh
28  push 05EFFB880h
29  push 0773BFF5Ch
30  push 0FB038Fh
31  mov al, [esp+8]
32  @
33  invoke ExitProcess, [esp]
34 testfunc ENDP
35 
36 END main

Windows:
If you would type the result of executing this, and compare:

C:\masm32\bin\ml /c /Zd /coff script_name.asm
C:\masm32\bin\Link /SUBSYSTEM:CONSOLE script_name.obj
script_name.exe
echo %ERRORLEVEL%

The program's exit status (printed with echo) would be a the number stored to stack memory with mov [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.

1 testfunc proc
2   mov eax, esp
3   mov bl, 0FFh
4   mov [eax], bl
5   COMMENT @
6   push 0FFFFh
7   push 05EFFB880h
8   push 0773BFF5Ch
9   push 0FB038Fh
10  mov al, [esp+8]
11  @
12  invoke ExitProcess, [esp]
13 testfunc ENDP

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++:

  • https://www.youtube.com/watch?v=vLnPwxZdW4Y&ab_channel=freeCodeCamp.org

    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

  • Please read the intel software developer manual, it tells you stuff like how if you change a position in memory, it's called the command register of advanced programmable interrupt controller would execute code in another core which is a CPU. You don't have to remember, just I recommend rewriting everything into txts, and then make a script to search for a word every new section you create a txt. I didn't even memorize anything from the book, I just know some stuff in the commonsense part of my mind, I hope you will know more for the reader.

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

  • I watched some of https://www.youtube.com/c/WhatsACreel videos because I was doing a chapter and had 30 day breaks between reading that so I could understand better. I recommend doing that too, but I don't know how to tell you when to stop and question your thinking to watch a video; I'm sorry.

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':

  • "a register name enclosed in brackets implies the contents of the location whose address is contained in that register."

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.

哭了丶谁疼 2024-08-24 23:31:25

它表明寄存器应该用作实际位置的指针,而不是作用于寄存器本身。

It indicates that the register should be used as a pointer for the actual location, instead of acting upon the register itself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文