Функция поворота в сборке x86_64 AT & T - PullRequest
0 голосов
/ 31 октября 2018

Я реализую функцию поворота в 64-битной сборке AT & T, и у меня возникают проблемы с получением правильного вывода в моем коде.

Я пытаюсь реализовать функцию

unsigned long rotate(unsigned long val, ul num, ul dir); 

Val - это значение, которое я хотел повернуть, num - это количество раз и направление влево или вправо, 0 - вправо, 1 - влево.

Мой код сборки:

.global rotate

rotate: #value = %rdi
        #num = %rsi 
        #direction = %rdx 
        mov %rsi, %r10 #puts num into register
        test %rdx, %rdx 
        jz right #if rdx is 0 jump to rotate right
        #else go to loop right below which rotates left
loop: 
     test %r10, %r10 #if num is 0 I am done
     jz done 
     rol $1, %rdi #rotate left 1 bit
     dec %r10 #decrement my count
     jmp loop #jump to top of loop 

 right: #same logic as left 
      test %r10, %10 
      jz done 
      rol $1, %rdi  
      dec %r10 
      jmp loop 
 done: 
      mov %rdi, %rax
      ret 

Мой код C:

#include <stdio.h> 
extern unsigned long rotate(unsigned long val, unsigned long num, unsigned long direction); 

int main()
{
unsigned long v,n,d; 
v = 0xDEADBEEFDEADBEEF; 
n = 2; 
d = 1; 

printf("%x\n ", rotate(v,n,d));    
}

Когда я компилирую и запускаю, я получаю значение 0x7AB6FBBF, когда я должен получить 0x7AB6FBBF7AB6FBBF.

Что-то не так с моими инструкциями, не отправляющими unsigned long с или что-то?

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

У вас есть ошибка в asm: ветвь цикла в right делает jmp loop вместо jmp right. По крайней мере, это одна ваших ошибок, IDK, если их больше. (обновление: @zch обнаружил ошибку в вашем C, которая объясняет усечение, о котором вы упоминаете.)

Это было бы легче определить, если бы вы использовали лучшее имя, чем loop. например left.

Но вы все равно не должны зацикливаться. В x86 есть rol %cl, %rdi и ror %cl, %rdi, которые вы можете использовать вместо цикла. Просто mov ваш сдвиг в %ecx, например mov %esi, %ecx.

0 голосов
/ 31 октября 2018

printf("%x", a) работает по типу unsigned int. На unsigned long вам нужно использовать "%lx" в качестве строки формата.

...