【问题标题】:Printing an entire array on a single line using printf asm nasm使用 printf asm nasm 在一行上打印整个数组
【发布时间】:2015-04-12 07:15:49
【问题描述】:

我正在使用 NASM 编译我的 ASM 程序,但我无法弄清楚如何使用循环在一行上打印整个数组(不一定知道数组有多大)。每当我使用 printf 创建一个循环时,它都会在多行而不是一行上打印值。知道如何使 printf 使用循环在单行上打印数组的多个值吗?我得到值 1-9 但都在不同的行而不是同一行。这是在不使用外部库的情况下完成的,除了:printf c 库。非常感激任何的帮助。我的代码如下。

  extern    printf  

 SECTION .data              ; Data section, initialized variables

array: dd 1, 2, 3, 4, 5, 6, 7, 8, 9, 0; this is a test array for testing purposes

arrayLen: dd 9  ; length of array 

aoutput: db "%d", 10, 0 ; output format

SECTION .text               ; Code section.

global main             ; the standard gcc entry point

main:                   ; the program label for the entry point
    push    ebp         ; set up stack frame
    mov     ebp,esp

    mov ecx, [arrayLen] ; loop counter set up
    mov esi, 0      ; counter to increment set up for looping through array
.loop:

    push ecx                                    ; make sure to put ecx (counter) on stack so we don't lose it when calling printf)
    push dword [array + esi]                    ; put the value of the array at this (esi) index on the stack to be used by printf
    push dword aoutput                          ; put the array output format on the stack for printf to use
    call printf                                 ; call the printf command
    add esp, 8                                  ; add 4 bytes * 2
    pop ecx                                     ; get ecx back

    add esi, 4
    loop .loop

    mov     esp, ebp    ; takedown stack frame
    pop     ebp         ; same as "leave" op

    mov     eax,0       ; normal, no error, return value
    ret                 ; return

【问题讨论】:

  • @JonathonReinhart 我同意你的看法。 Ikegami 感谢您的帮助,尽管当我要求汇编程序的一些语法时,这就是我所寻求的,因为在像 c++ 这样的另一种语言中,我知道如何在使用 cout 之类的东西时创建新行或不创建新行,但是对于汇编程序,语法有点不同,这就是我要问的,因为我已经知道我在寻找什么(不添加 \n)但我问的是如何不添加 \n,因为我没有不知道放在哪里,反正我找到了我正在寻找的答案。感谢大家的帮助。
  • 相关:如果您根本不打印换行符,您可能需要 fflush:Printf without newline in assembly

标签: arrays assembly syntax printf nasm


【解决方案1】:

问题是您在每个元素之后输出换行符。

以下是两个解决方案。它们都没有像现有的两种解决方案那样存在尾随空格的问题。

请注意,我对循环进行了轻微的重新排列以允许空数组。允许空数组是一种很好的做法,即使没有必要,因为它不需要任何额外的指令。


解决方案 1:如果是最后一个元素,则使用 "%d\n" 作为格式,否则使用 "%d "

如果您不想为空数组打印换行符,这很好。

format1: db "%d ", 0
format2: db "%d", 10, 0

    jmp .loop3

.loop1:
    mov eax,format1
    cmp ecx,1
    jnz .loop2

    mov eax,format2

.loop2
    push ecx
    push dword [array + esi]
    push dword eax
    call printf
    add esp, 8
    pop ecx

    add esi, 4

.loop3:
    loop .loop1

解决方案 2:如果它是第一个元素,则使用 "%d" 作为格式。否则使用" %d" 作为格式。在循环之后打印一个换行符。

如果您想为空数组打印换行符,这很好。

format1: db "%d", 0
format2: db " %d", 0

    mov eax, format1
    jmp .loop2

.loop1:
    push ecx
    push dword [array + esi]
    push dword eax
    call printf
    add esp, 8
    pop ecx

    add esi, 4
    mov eax, format2

.loop2:
    loop .loop1

    push 10
    call putchar

请原谅任何错误;上次我为 x86 编写程序集时,x86 没有eax 寄存器。在任何情况下,逻辑都应该是显而易见的。

【讨论】:

    【解决方案2】:

    我想通了(这与另一个答案相同,我在看到它发布之前才发现它)。

    我想通了,我把格式定义改成:

     aoutput: db "%d ", 0   ; output format
    

    来自:

     aoutput: db "%d ", 10, 0   ; output format
    

    并且刚刚添加了换行格式以在末尾添加新行。

     newline: db "", 10, 0    ; newline format
    

    【讨论】:

    • FWIW,如果您将字符串括在“反引号”(我们在这里用来表示代码的字符)中,Nasm 将识别“\n”和其他转义序列 - 而不是单引号或双引号。
    【解决方案3】:

    唯一决定某内容是打印在单行还是多行上的因素是您是否打印换行符 (\n)。

    在这里,当您说10 时,这是换行符的 ASCII 值。如果你改变这个:

    aoutput: db "%d", 10, 0 
    

    到这里:

    aoutput: db "%d ", 0 
    

    您的值将用空格而不是换行符分隔。

    在序列中的最后一个值之后,可以打印一个单独的换行符:

    push 0x0A     ; New line character
    call putchar
    

    【讨论】:

    • 请注意,您的解决方案会留下一个尾随空格。这可能很烦人,并可能导致屏幕出现空白行。
    猜你喜欢
    • 2013-12-14
    • 2019-07-06
    • 1970-01-01
    • 2015-09-17
    • 1970-01-01
    • 2013-06-02
    • 1970-01-01
    • 2015-06-09
    • 2015-09-16
    相关资源
    最近更新 更多