2016-09-11 3 views
0

Я пытаюсь перевести код сборки обратно в код C, но я заметил эту операцию под названием sarq. Я думаю, что q является для какого размера адресом, но я не знаю, что sarq делает по адресу. Я прокомментировал, что я считаю кодом.Язык ассемблера - что делает sarq в коде?

.LC0 .string "ans %d\n" 
main: 
.LFB0:     val = -8(%rbp), result = -12(%rbp) 
     pushq %rbp 
     movq %rsp, %rbp 
     subq $16, %rsp 
     movabsq $53162464113523643, %rax 
     movq %rax, -8(%rbp)  //val(variable) address -8,inputs value in %rax 
     movl $0, -12(%rbp)  //result(variable) address -12, inputs 0 
     jmp  .L2   //starts loop 
.L3: 
     movq -8(%rbp), %rax  //moves value in val into rax 
     andl $1, %eax  //dunno what eax is but adds 1 into it 
     xorl %eax, -12(%rbp)  //compares the value of eax and result to see if they are not equal. so compares 1 to 0 
     sarq -8(%rbp)  //does something to val? 
.L2: 
     cmpq $0, -8(%rbp)  //compares val to 0 
     jg  .L3   //if greater, goes to L3 
     movl -12(%rbp), %eax  //else, moves value from result into eax 
     movl %eax, %esi  //moves eax into esi 
     movl $.LC0, %edi  //Moves w/e $.LC0 is into edi. Based on the top, edi now holds that string? 
     movl $0, %eax  //moves 0 into eax 
     call printf   //print statement 
     leave 
     ret 
+0

[SAR задокументирован в справочнике по инсталляции Intel в комплекте] (http://www.felixcloutier.com/x86/SAL:SAR:SHL:SHR.html). См. Также http://stackoverflow.com/tags/x86/info –

ответ

1

sar - арифметическая правая смена. Одиночная форма операнда сдвигает операнд прямо на одно место, заполняя самый верхний бит знаком числа. суффикс q указывает, что операнд является 64-битным операндом (квадловым). Таким образом, sarq -8(%rbp) сдвигает квадрат в восемь байт ниже %rbp прямо на одно место.

+0

Итак, я бы преобразовал это верхнее число в двоичное, переместил его на 1 и добавил 0 infront из него? Итак, операция будет, если результат! = 1, а затем переместить его? –

+0

@JMei: b63 (самый значительный бит) сохраняет его значение (знак). Для бит b62-b0 сдвиг вправо на одно место означает, что b_i = b_old_i + 1. Таким образом, 0xAAAAAAAAAAAAAAAA превратится в 0xD555555555555555. 'shr' заполнил бы b63 нулем. 'sal' и' shl' оба сдвигают значение слева (тот же результат). 'sarq' является почти подписанным делением целого числа, за исключением' sar (-1) == -1' снова. Почему бы вам просто не проверить руководство по набору инструкций x86, а затем выполнить поиск некоторого учебника для инструкций по перемещению бит? Если вы хотите RE что-нибудь, у вас должен быть набор команд ref. от руки в любом случае. :) – Ped7g

3

andl $1, %eax //dunno what eax is but adds 1 into it

Uhmm ... eax ниже 32b часть rax. И это не add, но and. Таким образом, из значения quad только младший бит (b0) останется в eax.

Этот объект имеет xor-ed с результатом (первоначально нулевым).

И значение квадрата смещено вправо, с помощью сдвига сдвига, но константа положительна (0x00BCDEFABCDEFBBB), так что не имеет значения. В противном случае этот код закончится бесконечным циклом, для отрицательной константы! В этом случае программист-человек будет использовать shr, поэтому функция будет работать для любого значения 64b.

Таким образом, весь код вычисляет четность этой длинной константы (совершенно неэффективно, а также выглядит как неоптимизированный код), а затем печатает его как «ans # \ n», где # равно 0 (даже количество установленных бит) или 1 (нечетный).

(Я не отлаживал его, просто после его быстрого просмотра, так что, возможно, я что-то пропустил, вы должны попробовать в отладчике, что он действительно делает).


BTW, хорошая работа с этими комментариями, по крайней мере, было легко указать на другую проблему. Без них никто бы не заметил, и ему ответили бы только sarq.

Смежные вопросы