在x86_64程序集中输出链接列表的内容

问题描述

在获得链接列表以供我的Lisp编译器使用后,我希望能够打印列表的内容。这并不容易。我的链表的结构如下:每个节点为24个字节,前8个是用于描述头部类型的类型标记(1 = int,2 =列表),后8个是实际的头部数据,后8个是指向下一个节点的指针。我不知道为什么我的清单没有正确打印。我的输出12(我还没有打印任何空格或括号,所以应该是(1 (2)。为什么不进一步打印?我正在Mac上用Clang组装。

我的Lisp代码如下:

(define test_list (list_of (list_of 1 2) 3))
(display_a_list test_list)

由此,我的编译器生成了以下代码

    .global _main
    .text
_main:
    push 3  # push argument to list_of
    push 1  # type tag for list_of
    push 2  # push argument to list_of
    push 1  # type tag for list_of
    push 1  # push argument to list_of
    push 1  # type tag for list_of
    mov r13,2  # list of length 2
    call list_of
    add rsp,32  # discard 2 local arguments
    push rax  # result of list_of
    push 2  # type tag for list_of
    mov r13,32  # discard 2 local arguments
    mov [test_list + rip],rax
    mov rsi,[test_list + rip]
    push rsi  # push variable
    call display_a_list
    add rsp,8  # discard 1 local argument
    mov rdi,0
    mov rax,0x2000001
    syscall

    .data
test_list:
    .quad 0

这是我上面调用list_of过程(我已经验证了该过程可以正常工作):

/*
rbx = first iteration,true or false
r12 = arg offset
r13 = argument count
r14 = for saving tail address of prevIoUs
r15 = accumulator for result
*/

.macro argument_to_memory offset
mov rsi,[rbp + r12]
mov [rax + \offset],rsi
add r12,8
.endm

list_of:
    push rbp
    mov rbp,rsp
    mov r12,16
    imul r13,2
    mov rbx,1  # 1 for first time

    recur_make_list:
        mov rdi,24
        sub rsp,8
        call _malloc
        add rsp,8
        argument_to_memory 0
        argument_to_memory 8
        sub r13,2

        cmp r13,0
        je end_make_list

        cmp rbx,1
        je first_iteration
        jmp rest_of_iterations

        first_iteration:
            mov r15,rax  # save first head
            mov rbx,0

        rest_of_iterations:
            jne prev_tail_assign
            jmp save_tail  # if equal,don't assign prev
            prev_tail_assign:
                mov [r14],rax # prev tail = curr
            save_tail:
                lea r14,[rax + 16]  # save tail

            jmp recur_make_list

    end_make_list:
        mov qword ptr [rax + 16],0x00  # 0x00 = the new null!
        mov [r14],rax
        mov rax,r15
        mov rsp,rbp
        pop rbp
        ret

最后,这是我的display_list函数

    .global _main,display_a_list
    .text

display_a_list:
    push rbp
    mov rbp,rsp

    mov r12,[rbp + 16]

    push [r12 + 8]
    mov rsi,[r12]
    cmp rsi,1
    je print_atom  # tag 1 = print atom,otherwise print list
    jmp print_tail

    print_atom:
        call display_num
        jmp after_print_head

    print_tail:
        call display_a_list

    after_print_head:
        add rsp,8

    mov rsi,[r12 + 16]  # mov or lea?
    cmp rsi,0x00
    je end_print

    push rsi
    call display_a_list
    add rsp,8

    end_print:
        mov rsp,rbp
        pop rbp
        ret

最后但并非最不重要的一点是,这是我的宏,用于打印字符串,过程display_num等:

format_number:
    .asciz "%d"


.macro display_mac frm
    push rbp
    mov rbp,rsp
    mov rsi,[rbp + 16]
    lea rdi,\frm [rip]
    xor rax,rax
    call _printf
    mov rdi,0
    call _fflush
    mov rsp,rbp
    pop rbp
    ret
.endm

display_num: display_mac format_number

我已经编写了display_a_list函数的许多版本,但是它们都不起作用。请让我知道如何解决代码

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)