Bss 段 --> 无效的操作数组合
Bss section --> invalid combination of operands
我在 Linux.
下编程 nasm 遇到了问题
我的问题是
/home/maximilian/Schreibtisch/Programmierung/meinCompiler/var2.asm:6: warning: character constant too long
/home/maximilian/Schreibtisch/Programmierung/meinCompiler/var2.asm:6: error: invalid combination of opcode and operands
/usr/bin/ld: cannot find /home/maximilian/Schreibtisch/Programmierung/meinCompiler/var2.o: Datei oder Verzeichnis nicht gefunden
我的nasm代码:
section .data
section .text
global _start:
_start:
mov HALLO, "HALLO"
mov eax, 1
mov ebx, 0
int 0x80
section .bss
HALLO: resb 4
有人能帮帮我吗?
我搜索过这个主题,但没有找到任何关于 NASM-newb
的综合信息
希望你能回复我,
tfphd
如果在.data
中声明内存内容:
section .data
HALLO: db 'HALLO'
您将创建:
- 从编译点开始:一个名为
HALLO
的符号,其中包含指向 'H'
字符的地址
- 从 linux 可执行文件开始:包含字节
72,65,76,76,79
的 5 字节长数组,在读取-写入 初始化(通过加载可执行文件一次)内存区域.
现在您可以执行以下操作:
mov eax,HALLO ; loads value of symbol HALLO into register eax
; value of symbol HALLO is address of that array
mov DWORD [eax+2],0x454D504C ; writes number over 'LLO?' in that array
; creating string 'HALPME' in memory at address HALLO
; BUG: notice how 1 character is overwritten after the original array
; this may overwrite and destroy some other important value in .data
如果您要在 .rodata
部分中创建它,则尝试修改它是不明智的。有关详细信息,请参阅 NASM sections manual。
如果您在 .bss
中创建它,则数组应该未初始化,就像您最初所做的那样,将可执行文件加载到内存中只会保留 space,但不会对其进行初始化。
你不能这样做 mov HALLO, "HALLO"
,那不是 x86 程序集的工作方式。
最接近的是mov DWORD [HALLO],'HALL'
mov BYTE [HALLO+4],'O'
。在 32b 模式下,单条指令不能存储 5 个字节。
所以如果你想将一些内存数组设置为一些初始值字符串,要么使用 .data
部分,并在初始文本字节后添加行 times 64 db 0
以将其扩大 64 个字节(因此您可以稍后用更长的字符串覆盖它)。 - 如果你希望每个可执行文件初始化一次 运行.
或者将 'HALLO' 放入 .rodata 中,使用某种机制标记字符串的长度(在某处将其作为数字 5,或者在 O 之后添加第 6 个字节 0
或其他一些终止符($
在 DOS 中用于 int 21h)。并在 .bss 中创建足够长的缓冲区,如 stringBuffer: resb 69
。然后每次你想将它设置为 'HALLO'
,你必须复制从地址 HALLO
到地址 stringBuffer
.
的 5 个字节
顺便说一句,请注意在这样的例子中用符号 HALLO 命名值 'HALLO' 是多么的尴尬,因为现在你必须格外注意识别我在哪里谈论标签 (symbol/address) ,以及我将其用作文字值(字节)的地方。
总的来说,如果您刚开始使用 ASM,请从字符串转向数字(不要尝试输出它们,只需在调试器中 运行 并通过调试器观察 register/memory 值) .
熟悉byte/word/dword、地址和基本算术指令后,再看看字符串在内存中是如何编码的(ASCII/UTF-8/UTF-16),从数字机的位置看是怎样的( CPU)。或者按照任何 nasm 教程,它很可能会以一些 "hello world" 显示开始,这可能不会深入解释,为什么那个魔法 db 'hello world',10
作为字符串与 int 80h (eax,4 ;...).
最后,x86
标签上的信息非常大,包含许多进一步的资源:
https://whosebug.com/tags/x86/info
我在 Linux.
下编程 nasm 遇到了问题我的问题是
/home/maximilian/Schreibtisch/Programmierung/meinCompiler/var2.asm:6: warning: character constant too long
/home/maximilian/Schreibtisch/Programmierung/meinCompiler/var2.asm:6: error: invalid combination of opcode and operands
/usr/bin/ld: cannot find /home/maximilian/Schreibtisch/Programmierung/meinCompiler/var2.o: Datei oder Verzeichnis nicht gefunden
我的nasm代码:
section .data
section .text
global _start:
_start:
mov HALLO, "HALLO"
mov eax, 1
mov ebx, 0
int 0x80
section .bss
HALLO: resb 4
有人能帮帮我吗?
我搜索过这个主题,但没有找到任何关于 NASM-newb
的综合信息希望你能回复我,
tfphd
如果在.data
中声明内存内容:
section .data
HALLO: db 'HALLO'
您将创建:
- 从编译点开始:一个名为
HALLO
的符号,其中包含指向'H'
字符的地址 - 从 linux 可执行文件开始:包含字节
72,65,76,76,79
的 5 字节长数组,在读取-写入 初始化(通过加载可执行文件一次)内存区域.
现在您可以执行以下操作:
mov eax,HALLO ; loads value of symbol HALLO into register eax
; value of symbol HALLO is address of that array
mov DWORD [eax+2],0x454D504C ; writes number over 'LLO?' in that array
; creating string 'HALPME' in memory at address HALLO
; BUG: notice how 1 character is overwritten after the original array
; this may overwrite and destroy some other important value in .data
如果您要在 .rodata
部分中创建它,则尝试修改它是不明智的。有关详细信息,请参阅 NASM sections manual。
如果您在 .bss
中创建它,则数组应该未初始化,就像您最初所做的那样,将可执行文件加载到内存中只会保留 space,但不会对其进行初始化。
你不能这样做 mov HALLO, "HALLO"
,那不是 x86 程序集的工作方式。
最接近的是mov DWORD [HALLO],'HALL'
mov BYTE [HALLO+4],'O'
。在 32b 模式下,单条指令不能存储 5 个字节。
所以如果你想将一些内存数组设置为一些初始值字符串,要么使用 .data
部分,并在初始文本字节后添加行 times 64 db 0
以将其扩大 64 个字节(因此您可以稍后用更长的字符串覆盖它)。 - 如果你希望每个可执行文件初始化一次 运行.
或者将 'HALLO' 放入 .rodata 中,使用某种机制标记字符串的长度(在某处将其作为数字 5,或者在 O 之后添加第 6 个字节 0
或其他一些终止符($
在 DOS 中用于 int 21h)。并在 .bss 中创建足够长的缓冲区,如 stringBuffer: resb 69
。然后每次你想将它设置为 'HALLO'
,你必须复制从地址 HALLO
到地址 stringBuffer
.
顺便说一句,请注意在这样的例子中用符号 HALLO 命名值 'HALLO' 是多么的尴尬,因为现在你必须格外注意识别我在哪里谈论标签 (symbol/address) ,以及我将其用作文字值(字节)的地方。
总的来说,如果您刚开始使用 ASM,请从字符串转向数字(不要尝试输出它们,只需在调试器中 运行 并通过调试器观察 register/memory 值) .
熟悉byte/word/dword、地址和基本算术指令后,再看看字符串在内存中是如何编码的(ASCII/UTF-8/UTF-16),从数字机的位置看是怎样的( CPU)。或者按照任何 nasm 教程,它很可能会以一些 "hello world" 显示开始,这可能不会深入解释,为什么那个魔法 db 'hello world',10
作为字符串与 int 80h (eax,4 ;...).
最后,x86
标签上的信息非常大,包含许多进一步的资源:
https://whosebug.com/tags/x86/info