Сборочный цикл x86-64 - PullRequest
       22

Сборочный цикл x86-64

2 голосов
/ 14 января 2020

Этот вопрос был предложен мне другом, и я понятия не имею, как его решить.

loop:
    leal (%rdi, %rdi, 4), %eax
    leal (%rsi, %rax, 2), %eax
    leal 0(, %rax, 4), %edx
    cmpl %edx, %esi
    jge .L1
    leal (%rdi, %rdi, 2), %edx
.L3:
    addl %edx, %eax
    cmpl $-2, %esi
    jl .L3
.L1:
    rep ret

И он должен отображаться на этот l oop в C,

int loop(int a, int b){
    int x, y;
    y = ____;
    for (____; ____; ____){
        ____;
    }
    return ____;
}

Моя попытка преобразовать сборку в C,

y = 5a;
y = b + 2y;
x = 4y;
if (x < b){
    x = 3a;
    do{
        y += x;
    } while (b <= -2);
}
return y;

Я предположил% eax = y, поскольку 'y' в коде для заполнения - это первая назначаемая переменная. 'x' следует как% edx, так как это другое присваивание, и поэтому должно быть как минимум частью "Инициализации" for для l oop. Однако, это, кажется, не исправляет предоставленные пробелы, поэтому я действительно застрял.

1 Ответ

1 голос
/ 14 января 2020

Я думаю, что у меня есть действительно близкое, если не идеальное решение:

/* rdi = a, rsi = b */
/* rax = y, rdx = x */

/*
loop:
    leal (%rdi, %rdi, 4), %eax
    leal (%rsi, %rax, 2), %eax
    leal 0(, %rax, 4), %edx
    cmpl %edx, %esi
    jge .L1
    leal (%rdi, %rdi, 2), %edx
.L3:
    addl %edx, %eax
    cmpl $-2, %esi
    jl .L3
.L1:
    rep ret
*/

int loop(int a, int b){
    int x, y;
    y = b + (a * 5) * 2;
    for (x = y * 4; x > b;){
        do y += (x = a * 3); while(b < -2);
        break;
    }
    return y;
}

Не уверен, что break; - это проблема, но я не могу найти лучший путь.

...