简体   繁体   English

使用printf asm nasm在一行上打印整个阵列

[英]Printing an entire array on a single line using printf asm nasm

I am using NASM for compiling my ASM program and I am having trouble figuring out how to print an entire array on a single line (without necessarily knowing how big the array is) using a loop. 我正在使用NASM来编译我的ASM程序,但是我很难弄清楚如何使用循环在一行上打印整个阵列(不必知道该阵列有多大)。 Whenever I create a loop with printf it prints the values on multiple lines instead of one line. 每当我用printf创建一个循环时,它都会在多行而不是一行上打印值。 Any idea how to make printf print multiple values of an array on a single line using a loop? 任何想法如何使printf使用循环在一行上打印数组的多个值? I get values 1-9 but all on a different line instead of the same line. 我得到的值是1-9,但都在不同的行而不是同一行。 This is to be done without using external libraries other than: the printf c library. 无需使用除printf c库以外的外部库即可完成此操作。 Any help would be most appreciated. 非常感激任何的帮助。 The code I have is below. 我的代码如下。

  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

The only thing that determines whether something is printed on a single line or multiple, is if you print a newline character ( \\n ) or not. 决定是将一行打印还是多行打印的唯一方法是是否打印换行符( \\n )。

Here, when you say 10 , that is the ASCII value for a Line Feed. 在这里,当您说10 ,这是换行的ASCII值。 If you change this: 如果您更改此设置:

aoutput: db "%d", 10, 0 

to this: 对此:

aoutput: db "%d ", 0 

your values will be separated by spaces, instead of by new lines. 您的值将用空格(而不是换行)分隔。

After the final value in the sequence, you can print a lone newline character: 在序列的最终值之后,您可以打印一个孤独的换行符:

push 0x0A     ; New line character
call putchar

I figured out this (which is the same as the other answer, I just found it out before I saw it was posted). 我发现了这一点(与其他答案相同,只是在看到它发布之前就发现了)。

I figured it out, I changed the format definition to: 我知道了,我将格式定义更改为:

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

from: 从:

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

and just added an newline format to add a new line at the end. 并添加了换行符格式以在末尾添加新行。

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

The problem is that you are outputting a line feeds after each element. 问题是您要在每个元素之后输出换行符。

What follows are two solution. 以下是两个解决方案。 Neither of them suffer from the problem of leaving a trailing blank space as the two existing solutions do. 正如现有的两个解决方案一样,它们都没有留下尾随空白的问题。

Note that I made a slight rearrangement of the loop to allow empty arrays. 请注意,我对循环进行了一些重新排列,以允许使用空数组。 Allowing empty arrays is a good practice even if it's not necessary since it doesn't require any extra instructions. 即使没有必要,允许空数组也是一种好习惯,因为它不需要任何额外的说明。


Solution 1: Use "%d\\n" as the format if it's the last element or "%d " otherwise. 解决方案1:如果它是最后一个元素,则使用"%d\\n"作为格式,否则使用"%d "

This is good if you don't want to print the line feed for empty arrays. 如果您不想为空数组打印换行符,这很好。

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

Solution 2: Use "%d" as the format if it's the first element. 解决方案2:如果是第一个元素,请使用"%d"作为格式。 Use " %d" as the format otherwise. 否则,请使用" %d"作为格式。 Print a line feed after the loop. 在循环之后打印换行符。

This is good if you want to print the line feed even for empty arrays. 如果您要打印换行符(即使是空数组)也很好。

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

Pardon any errors; 请原谅任何错误; the x86 didn't have an eax register the last time I wrote assembly for it. 我上次为它编写程序集时,x86没有eax寄存器。 The logic should be evident in any case. 在任何情况下,逻辑都应显而易见。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM