Bss部分 - >操作数的无效组合

时间:2016-07-29 09:18:43

标签: 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 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

1 个答案:

答案 0 :(得分:2)

如果您要在.data中声明内存内容:

section .data
HALLO: db 'HALLO'

你会创建:

  • 从编译点开始:名为HALLO的符号,其中包含指向'H'字符的地址
  • 从linux可执行文件的角度来看:包含字节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}}。

顺便说一句,请注意命名值' HALLO'在这样的例子中,使用符号HALLO是非常尴尬的,因为现在你必须特别注意识别我在谈论标签(符号/地址)的位置,以及我在哪里使用它作为文字值(字节)

总的来说,如果您刚刚开始使用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