繁体   English   中英

尝试转换C程序以将数字反向转换为x86汇编

[英]Trying to translate C program to reverse a number into x86 assembly

我正在尝试将以下程序转换为x86汇编(AT&T)。

#include <stdio.h>

int main()
{
   int n = 123;
   int reverse = 0;


   while (n != 0)
   {
      reverse = reverse * 10;
      reverse = reverse + n%10;
      n       = n/10;
   }

   printf("%d\n", reverse);

   return 0;
}

应该打印321。

但是,使用下面的代码,我得到的是0。 有人能给我一个关于我在这里做错了什么的线索吗? (我只粘贴了下面的相关部分。我确定初始化和打印可以正常工作。您可以在这里看到整个内容

  movl  $123, %esi    # int n
  movl  $0, %edi    # int reverse
  movl $10, %ebx    # divisor


L1:     # while n != 0

cmpl $0, %esi
je L2

# reverse = reverse * 10
imul $10, %edi

# reverse = reverse + n % 10
movl $0, %edx
movl %edi, %eax
idivl %ebx
addl %edx, %edi

# n = n / 10
movl %esi, %eax
movl $0, %edx
idivl %ebx
movl %eax, %esi

jmp L1

L2:  # end while

movl %edi, %eax

也许我还不太了解idivl命令应该做什么。 我知道它会将%edx:%eax除以%ebx,并将商数存储在%eax中,其余部分存储在%edx中。

# reverse = reverse + n % 10
movl $0, %edx
movl %edi, %eax   ; <--- here

根据上面的评论, %edi不是n

movl  $123, %esi    # int n

因此,应使用%esi ,即movl %esi, %eax

有时最好看看编译器生成什么

int reverse(int x)
{
   int r = 0;

   while (x != 0)
   {
      r = r * 10;
      r = r + x%10;
      x = x/10;
   }
   return r;
}

最短的版本:

reverse:
  xor eax, eax
  mov esi, 10
.L2:
  test edi, edi
  je .L5
  imul ecx, eax, 10
  mov eax, edi
  cdq
  idiv esi
  mov edi, eax
  lea eax, [rdx+rcx]
  jmp .L2
.L5:
  ret

或最快的:

reverse:
  xor eax, eax
  test edi, edi
  je .L4
  mov esi, 1717986919
.L3:
  lea ecx, [rax+rax*4]
  mov eax, edi
  imul esi
  mov eax, edi
  sar eax, 31
  sar edx, 2
  sub edx, eax
  lea eax, [rdx+rdx*4]
  add eax, eax
  sub edi, eax
  test edx, edx
  lea eax, [rdi+rcx*2]
  mov edi, edx
  jne .L3
  rep ret
.L4:
  rep ret

如您所见,编译器比99.99%的编码器好/好

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM