Linux Bss部分-->;无效的操作数组合
我在Linux下编程nasm时遇到问题 我的问题是Linux Bss部分-->;无效的操作数组合,linux,assembly,nasm,Linux,Assembly,Nasm,我在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 o
/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新手
我希望你能回应我
tfphd如果要在
中声明内存内容。数据
:
section .data
HALLO: db 'HALLO'
您将创建:
- 从编译点开始:一个名为
的符号,其中包含指向HALLO
字符的地址'H'
- 从linux可执行文件的角度来看:5字节长的数组,包含字节
,位于读写初始化(通过加载可执行文件一次)内存区域72,65,76,76,79
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
部分中创建它,那么尝试修改它是不明智的。有关详细信息,请参阅
如果在.bss
中创建该数组,则应取消初始化该数组,就像最初一样,将可执行文件加载到内存中只会保留该空间,而不会对其进行初始化
您不能做mov-HALLO,“HALLO”
,x86汇编程序不是这样工作的。
最接近它的是mov-DWORD[HALLO],'HALL'
mov-BYTE[HALLO+4],'O'
。在32b模式下,单条指令不能存储5个字节
因此,如果要将某个内存数组设置为某个初始值字符串,可以使用.data
部分,并在初始文本字节后添加行乘以64 db 0
,将其放大64字节(以便以后可以用更长的字符串覆盖)如果希望每次可执行文件运行时初始化一次
或者将“HALLO”放入.rodata中,使用某种机制标记字符串的长度(或者在某处将其作为数字5,或者使用0
或其他终止符在O后添加第6字节($
在DOS中用于int 21h)。并在.bss中创建足够长的缓冲区,如stringBuffer:resb 69
。然后每次要将其设置为'HALLO'
,必须将5个字节从addressHALLO
复制到addressstringBuffer
顺便说一句,注意在这样的例子中,用符号HALLO命名值“HALLO”是多么的笨拙,因为现在您必须特别注意识别我在哪里谈论标签(符号/地址),以及我在哪里使用它作为文字值(字节)
总的来说,如果您刚开始使用ASM,请从字符串移动到数字(不要尝试输出它们,只需在调试器中运行并通过调试器查看寄存器/内存值)
熟悉字节/字/dword、地址和基本算术指令后,检查字符串在内存中的编码方式(ASCII/UTF-8/UTF-16),以及从数字机器(CPU)的位置看它是什么样子。或者遵循任何nasm教程,它很可能从一些“hello world”开始显示,这可能无法深入解释为什么神奇的db'helloworld',10
可以作为int 80h的字符串(eax,4;…)
最后,
x86
标记上的信息非常大,包含许多其他资源:如果您要在
中声明内存内容。data
:
section .data
HALLO: db 'HALLO'
您将创建:
- 从编译点开始:一个名为
的符号,其中包含指向HALLO
字符的地址'H'
- 从linux可执行文件的角度来看:5字节长的数组,包含字节
,位于读写初始化(通过加载可执行文件一次)内存区域72,65,76,76,79
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
部分中创建它,那么尝试修改它是不明智的。有关详细信息,请参阅
如果在.bss
中创建该数组,则应取消初始化该数组,就像最初一样,将可执行文件加载到内存中只会保留该空间,而不会对其进行初始化
您不能做mov-HALLO,“HALLO”
,x86汇编程序不是这样工作的。
最接近它的是mov-DWORD[HALLO],'HALL'
mov-BYTE[HALLO+4],'O'
。在32b模式下,单条指令不能存储5个字节
因此,如果要将某个内存数组设置为某个初始值字符串,可以使用.data
部分,并在初始文本字节后添加行乘以64 db 0
,将其放大64字节(以便以后可以用更长的字符串覆盖)。-如果希望每次可执行运行时初始化一次
或者将“HALLO”放入.rodata中,使用某种机制标记字符串的长度(或者在某处将其作为数字5,或者使用0
或其他终止符在O后添加第6字节($
在DOS中用于int 21h)。并在.bss中创建足够长的缓冲区,如stringBuffer:resb 69
。然后每次要将其设置为'HALLO'
,必须将5个字节从addressHALLO
复制到addressstringBuffer
顺便说一句,注意在这样的例子中,用符号HALLO命名值“HALLO”是多么的笨拙,因为现在您必须特别注意识别我在哪里谈论标签(符号/地址),以及我在哪里使用它作为文字值(字节)
总的来说,如果您刚开始使用ASM,请从字符串移动到数字(不要尝试输出它们,只需在调试器中运行并通过调试器查看寄存器/内存值)
熟悉字节/字/dword、地址和基本算术指令后,检查字符串在内存中的编码方式(ASCII/UTF-8/UTF-16),以及从数字机器(CPU)的位置看它是什么样子。或者遵循任何nasm教程,它很可能从一些“hello world”开始显示,这可能无法深入解释为什么神奇的db'helloworld',10
可以作为int 80h的字符串(eax,4;…)
最后,
x86
标记上的信息非常大,包含许多f