首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在汇编中将数组打印为双字

在汇编中将数组打印为双字
EN

Stack Overflow用户
提问于 2020-12-17 12:28:30
回答 1查看 101关注 0票数 1
代码语言:javascript
复制
%include "asm_io.inc"
;
; initialized data is put in the .data segment
;
segment .data
array: dd 180,32,455,499,388,480,239,346,257,84
fmt: dd ",%d",0

; uninitialized data is put in the .bss segment
;
segment .bss
 resd 10
;
; code is put in the .text segment
;
segment .text
        extern  printf
        global  asm_main
asm_main:
        enter   0,0               ; setup routine
        pusha

; The following is just example of how to print an array

        push dword 10
        push dword array
        call print_array
        add  esp,8                ; clean up stack

; don't delete anything following this comment
        popa
        mov     eax, 0            ; return back to C
        leave                     
        ret



segment .data
ListFormat    db   ",%u", 0

segment .text
        global  print_array
print_array:
        enter   0,0
        push    esi
        push    ebx

        xor     esi, esi                  ; esi = 0
        mov     ecx, [ebp+12]             ; ecx = n
        mov     ebx, [ebp+8]
        xor     edx, edx
        mov     dl, [ebx + esi]     ; ebx = address of array
        mov     eax,edx             
        call    print_int
        dec     ecx
        inc     esi

print_loop:
        xor     edx,edx
        mov     dl,[ebx + esi]
        push    ecx                       ; printf might change ecx!
        push    edx                       ; push array value
        push    dword ListFormat
        call    printf
        add     esp, 8              ; remove parameters (leave ecx!)
        inc     esi
        pop     ecx
        loop    print_loop
        call    print_nl

        pop     ebx
        pop     esi
        leave
        ret

所以当我想打印180,32,455,499,388,480,239,346,257,84时,这个代码会打印出180,0,0,0,32,0,0,0,199,1。我认为这是因为它是为打印字节字而设计的。我正在尝试以双字打印,我猜print_array中的某些内容需要更改。我尝试了mov dl,ebx+esi*4,但它仍然没有打印出我想要打印的数组。或者,是否需要将其他内容更改为打印双字数组?

EN

回答 1

Stack Overflow用户

发布于 2020-12-17 23:38:29

您可以将mov dl, [ebx+esi]指令更改为mov edx, [ebx+esi*4],但这只是一半的乐趣!

1为什么不尝试创建一个循环来处理列表中不需要逗号前缀的第一个值的特殊情况?不再使用print_int

2也不使用LOOP指令。太慢了!配对cmp jb (可以进行宏观融合)要好得多。

3和通过简单地通过ESP相对寻址来寻址参数来替换prolog enter 0,0和epilog leave代码非常简单。

4总是考虑特殊情况!如果数组碰巧是空的怎么办?

代码语言:javascript
复制
print_array:
        push    ebx
        push    esi
        mov     ebx, [esp+12]       ; Begin array
        mov     esi, [esp+16]       ; n
        test    esi, esi
        jz      done

        lea     esi, [ebx+esi*4]    ; End array
        mov     edx, ListFormat+1   ; "%u"
more:   mov     eax, [ebx]          ; Array dword value
        push    eax
        push    edx                 ; "%u" first time, ",%u" others
        call    printf
        add     esp, 8
        add     ebx, 4              ; To next dword in the array
        mov     edx, ListFormat     ; ",%u"
        cmp     ebx, esi            ; Current address < Last address ?
        jb      more                ; Yes
        call    print_nl

done:   pop     esi
        pop     ebx
        ret

在适当的条件下,将ESP固定在这个循环中是值得做的。请参阅此答案下面Peter Cordes的评论。

接下来是这段代码的一个版本,它将ESP固定在循环中:

代码语言:javascript
复制
print_array:
        push    ebx
        push    esi
        mov     ebx, [esp+12]       ; Begin array
        mov     esi, [esp+16]       ; n
        test    esi, esi
        jz      done

        sub     esp, 8              ; Space for the printf args
        lea     esi, [ebx+esi*4]    ; End array
        mov     edx, ListFormat+1   ; "%u"
more:   mov     eax, [ebx]          ; Array dword value
        mov     [esp+4], eax
        mov     [esp], edx          ; "%u" first time, ",%u" others
        call    printf
        add     ebx, 4              ; To next dword in the array
        mov     edx, ListFormat     ; ",%u"
        cmp     ebx, esi            ; Current address < Last address ?
        jb      more                ; Yes
        call    print_nl
        add     esp, 8

done:   pop     esi
        pop     ebx
        ret
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65334735

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档