2016-10-09 13 views
0

Я делаю проект класса, который я должен взять на C-код, включите его в сборке x86-64, а затем измените его на Y86. В этом я должен вернуть сумму элементов в связанном списке в rax. Однако, когда я пытаюсь использовать компилятор y86, он не появляется. Y86 я сделал выглядел следующим образом:Код Y86 - не возвращает или не показывает rax

.pos 0 
irmovq Stack,%rsp 
irmovq Stack,%rbp 
jmp Main 

Main: 
     irmovq ele1,%rax 
     pushq %rax 
     call sum_list 
     halt 

sum_list: 
     pushq %rbp 
     rrmovq %rsp,%rbp 
     irmovq $24,%rdx 
     subq %rdx,%rsp 
     irmovq $0,%rdx 
     rmmovq %rdx,-8(%rbp) 
     jmp L2 
L3: 
     mrmovq 24(%rbp),%rax 
     mrmovq (%rax),%rax 
     mrmovq -8(%rbp),%rdx 
     addq %rax,%rdx 
     rmmovq %rdx,-8(%rbp) 
     mrmovq 24(%rbp),%rax 
     mrmovq -8(%rax),%rax 
     rmmovq %rax,24(%rbp) 
L2: 
     irmovq $0,%rcx 
     mrmovq 24(%rbp),%rdx 
     subq %rcx,%rdx 
     jne L3 
     mrmovq -8(%rbp),%rax 
     rrmovq %rbp,%rsp 
     popq %rbp 
     ret 

#linked-list 
.align 8 
ele1: 
     .quad 0x00d 
     .quad ele2 
ele2: 
     .quad 0x0e0 
     .quad ele3 
ele3: 
     .quad 0xf00 
     .quad 0 

.pos 0x500 
Stack: 

И так rax должен 0xfed, но в моем результате, ничего не появляется.

Это код C Я получил его от:

typedef struct ELE{ 
    long val; 
    struct ELE *next; 
} *list_ptr 

long sum_list(list_ptr ls){ 
    long val = 0; 
    while(ls){ 
    val += ls->val; 
    ls = ls->next; 
    } 
    return val; 
} 
+0

Никто не хочет читать этот дрянной неуправляемый вывод компилятора, который хранит все в стек после каждого утверждения. А что значит «ничего не появляется»? Регистр всегда имеет значение, даже если оно равно нулю. Вы уверены, что правильно напечатали результат? Вы смотрели RAX с отладчиком? –

+0

Кстати, нормальный стиль в C должен был сделать typedef для struct (а не указателем на структуру), а затем написать 'const list_elem * p'. Это делает очевидным, что это указатель еще до чтения имени. Когда я смотрю на 'long sum_list (list_ptr ls)', мое первоначальное впечатление заключается в том, что это функция, которая принимает что-то по значению. (Что технически верно, указатель имеет значение.) –

+0

@PeterCordes Я использую yas и yis для компиляции и выполнения моих файлов. И это показывает, когда меняются регистры. Тем не менее, он ничего не показывает о% rax –

ответ

2

Глядя на код, то кажется, что указатель на узел должен быть на 16 (РСП), а не 24 (РСП). 0 (rbp) = сохраненное значение rbp, 8 (rbp) = обратный адрес, 16 (rbp) = указатель на узел (в связанный список). Я не вижу, куда лишние 8 байтов помещаются в стек до того, как будет сохранено rbp.

Программа заканчивается инструкцией по остановке. Можете ли вы определить содержимое rax, когда это произойдет (например, с помощью отладчика)?

+0

Я думаю, что вы правы, они используют неправильное смещение RBP. Было бы разумнее передать функцию arg в RDI (например, x86-64 SystemV ABI). Я думал, что этот глупый беспорядок кода должен был быть выходом компилятора (очевидно, из '-O0' вместо' -O3')? OP сказал, что они использовали компилятор y86, поэтому IDK как эта ошибка была введена. Во всяком случае, я вижу, что код делает RSP - = 24, может быть, вот откуда пришли 24? '16 (% rbp)' смотрит мне прямо. BTW, '$ 10' не является« 0x10 »в синтаксисе газа (я предполагаю, что y86 тот же). синтаксис AT & T газа использует '$' для непосредственных констант. –

+0

Спасибо! Он работает после внесения исправлений. –

+0

Спасибо за комментарий о $ instantiates. Я удалил это из своего ответа. Вычитание 24 из rsp не влияет на rbp, так что это не проблема. – rcgldr