我在 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
my nasm Code:
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
答案 0 :(得分:2)
如果您要在.data
中声明内存内容:
section .data
HALLO: db 'HALLO'
你会创建:
HALLO
的符号,其中包含指向'H'
字符的地址72,65,76,76,79
的5字节长数组,在read- write 初始化(一次通过加载可执行文件)内存区域。所以现在你可以做以下事情:
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
中创建它,那么数组应该是未初始化的,就像你原来一样,将可执行文件加载到内存中只会保留该空间,但不会初始化它。
你不能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'
时,必须将5个字节从地址HALLO
复制到地址{{ 1}}。
总的来说,如果您刚刚开始使用ASM,请从字符串移动到数字(并且不要尝试输出它们,只需在调试器中运行并通过调试器查看寄存器/内存值)。
熟悉字节/字/双字,地址和基本算术指令后,检查字符串在内存中的编码方式(ASCII / UTF-8 / UTF-16),以及它从数字位置的外观机器(CPU)。或者按照任何nasm教程,它很可能从一些" hello world"开始。显示,可能无法深入解释,为什么魔术stringBuffer
作为字符串使用int 80h(eax,4; ...)。
最后,db 'hello world',10
标记上的信息非常大,包含许多其他资源:
https://stackoverflow.com/tags/x86/info