【问题标题】:How to declare an array with size indicated by the user in nasm?如何在 nasm 中声明用户指定大小的数组?
【发布时间】:2019-04-06 17:00:43
【问题描述】:

想用 nasm 做一个使用 x86 架构的例子,它可以创建一个大小为“n”的数组,其中“n”将是用户希望在运行时拥有数组大小的数字

extern _printf
extern _scanf
extern _scanf
global _main

section .data
    array:  10,5,4
    msg:    db  "enter the size of the array: ",10,0
    size:   db 10
    format: db "%i",0
section .text
    _main:
          push msg
          call _printf
          add esp, 4

          push size
          push format
          call _scanf
          add esp, 8

    ret

【问题讨论】:

  • 汇编语言中没有声明。你能详细说明你想做什么吗?
  • 你需要在运行时分配。堆栈或堆。与 C 相同。
  • 数组不应该有烧掉的大小,但应该在从控制台捕获时指出
  • 你不能在汇编中这样做。您必须首先从用户那里获取大小,然后使用外部内存管理功能从堆中分配该内存量。或在堆栈上保留那么多(但不要太多——堆栈相对较小)。您调用哪个函数取决于代码将在其中运行的环境。我猜在 C 中,您会调用 malloc。在独立应用程序中,您将调用 OS 函数。等
  • 谢谢,我更倾向于第二部分,但是为向量保留足够的内存空间并不是一个坏习惯

标签: assembly x86 nasm intel


【解决方案1】:

你的意思是像BSS中的resd n,用户可以用nasm -felf -Dn=1024构建程序,将NASM宏设置为常量吗?您可以使用%ifdef 提供默认值。

如果你想要一个运行时可变的数组大小,它显然不能在静态存储中(除非你大量过度分配并且只使用需要的数组的任何部分。这在为BSS。)

【讨论】:

  • 你能给我举个例子吗
【解决方案2】:

如果您对 Windows 示例感到满意,请参阅 EuroAssembler 中的以下程序。它会创建 3128 字节长的 AllocArray.exe,它将在 BSS 部分保留和初始化请求的大小。

AllocArray PROGRAM Format=PE, IconFile=, Entry=Main:
           INCLUDE winapi.htm, cpuext32.htm
%MaxPossibleLength %SETA 1_000_000 ; Specify the maximal acceptable allocation here.
[.text]
Main: StdOutput ="Enter the size of the array (1..%MaxPossibleLength): "
      StdInput EnterredLength    ; Let the user to set array length.
      LodD EnterredLength        ; Convert the enterred decimal number to integer in EAX.
      CMP EAX,%MaxPossibleLength
      JA Main:
      MOV [LengthOfTheArray],EAX
      StoD AllocatedLength       ; Convert the integer EAX to decimal.
      XOR EAX,EAX
      STOSB                      ; Zero-terminate the decimal number.
      MOV EDI,TheArray:
      MOV ECX,[LengthOfTheArray]
      MOV EAX,0x5A5A5A5A
      REP STOSD                  ; Initialize the array with 5A.
      StdOutput ="The array of ", AllocatedLength, =" DWORDs is now allocated statically."
      TerminateProgram
[.bss]
EnterredLength:   DB 16 * BYTE  
AllocatedLength:  DB 16 * BYTE  
LengthOfTheArray: DD DWORD
TheArray:         DD %MaxPossibleLength * DWORD
      ENDPROGRAM AllocArray

【讨论】:

  • 这不是 NASM 语法。我认为这是 FASM 语法(绝对不是 MASM,MOV EDI,TheArray: 将是 MASM 中的负载,或者由于: 而无效)。如果其他人错过了它,StoD 不是stosd,它是一个宏或这个答案没有定义的东西,但显然 EDI 指向字符串的末尾。这段代码的大部分是打印输出,而不是实际的分配和 `memset(TheArray, 0x5A, LenthOfTheArray)。
  • OP 要求提供 massively ovet-allocate 的示例,并且只使用需要的数组的任何部分
  • 确实,StoD 不是mavhine 指令,printfmemset 也不是。 StoD 是随 €ASM 一起提供的格式化打印宏:euroassembler.eu/maclib/cpuext32.htm#StoD
  • 是的,但通常你会使用call printf,所以没有空间将它与机器指令混淆。而且你使用的StoD 非常接近STOSB,所以很容易混淆它是什么。但更重要的是,在您发表评论之前,这个答案甚至没有说明它需要什么汇编程序。它不适用于 NASM,这是 OP 要求的示例。
  • 其实代码一定是nasm的,因为语言之间,很多东西都变了。但事实是,我制作了一个固定大小的数组,并在输入数组的大小时指定了用户,它必须创建它的最大值,因为正如他们在上面评论的那样,你不能动态创建数组,你总是必须有一个尺寸,还有其他人告诉我这个社区之外的人。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多