在程序集x86中将十进制转换为二进制 [英] Converting decimal to binary in assembly x86

查看:51
本文介绍了在程序集x86中将十进制转换为二进制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将十进制数写入二进制转换器,对于某些数字,它起作用,而对于另一些数字,则不起作用.0-8木材工作正常,但是当我输入9时显示101.我已经尝试修复此代码几个小时了,但我找不到它出了什么问题.

I'm trying to write decimal to binary converter and for some numbers it works and for others it doesn't. 0 - 8 mumbers works fine, but when I input 9 it displays 101. I have been trying to fix this code for few hours now and I can't find out what's wrong with it.

SYSEXIT = 1
SYSREAD = 3
SYSWRITE = 4
STDOUT = 1
STDIN = 0

.bss                                   
.equ bufsize, 32               
.lcomm buf, bufsize             #buf - saved user input

.equ buf2size, 32              
.lcomm buf2, buf2size           #binary in wrong order

.equ buf3size, 32              
.lcomm buf3, buf2size           #binary correct order

.data

msg_podaj:
.ascii "Wprowadz liczbe:\n"
msg_dlpodaj = .- msg_podaj

msg_test:
.ascii "TEST\n"
msg_dltest = .- msg_test

.text
.global _start

_start:


mov $SYSWRITE, %eax                             
mov $STDOUT, %ebx
mov $msg_podaj, %ecx
mov $msg_dlpodaj, %edx
int $0x80

mov $SYSREAD, %eax                              
mov $STDIN, %ebx
mov $buf, %ecx
mov $bufsize, %edx
int $0x80

xor %eax, %eax
xor %ecx, %ecx

mov $0, %edi                            
movb buf(,%edi,), %al                   
sub $48, %eax                           

read:
incl %edi                                            
movb buf(,%edi,), %cl                   
sub $48, %ecx


cmp $0, %cl                            
jl tu                                   
cmp $9, %cl                             
jg tu                              

imul $10, %eax                          
add %ecx, %eax                         

jmp read

tu:

mov $0, %edi                            
mov $0, %edx
mov $2, %ebx

cmp $0, %eax
je wstaw

movb $'1', buf3(,%edi,)
jmp loop

wstaw:
movb $'0', buf3(,%edi,)

loop:
cmp $1, %eax
jle changeorder

incl %edi
DIV %ebx
mov %edx, buf2(,%edi,)
add $'0', buf2(,%edi,)

jmp loop

changeorder:
mov $1, %esi

loop2:
cmp $0, %edi
je display

movb buf2(,%edi,), %ah
movb %ah, buf3(,%esi,)
incl %esi
decl %edi
jmp loop2

display:
mov $SYSWRITE, %eax
mov $STDOUT, %ebx
mov $buf3, %ecx
mov $buf3size, %edx
int $0x80

exit:                                         
mov $SYSEXIT, %eax
int $0x80

推荐答案

您的代码可以简化很多(而简单的代码通常意味着更容易发现任何错误).这是实现此目的的更简单方法的概述(我将由您自己决定如何在x86汇编中实现它):

Your code could be simplified a lot (and simpler code usually means that it's simpler to find any mistakes). Here's an outline of an easier way of doing this (I'll leave it up to you to implement it in x86 assembly):

void to_bin_string(unsigned input) {
  char output[33];

  // The number of binary digits needed to represent the input number, if we
  // exclude leading zeroes.
  unsigned digits = highest_set_bit(input) + 1;

  // Shift the input so that the most significant set bit is in bit 31.
  input <<= (32 - digits);

  for (unsigned i = 0; i < digits; i++) {
    // If the current msb is set, store a '1' in the output buffer. Otherwise
    // store a '0'.
    output[i] = (input & 0x80000000) ? '1' : '0';
    // Move the second-most significant bit into the msb position.
    input <<= 1;
  }
  output[digits] = '\0';
}

您可以使用 BSR 指令来计算x86 CPU上的 highest_set_bit .可以使用 AND TEST 完成& 操作,而<< 将是 SHL .

You can use the BSR instruction to compute highest_set_bit on x86 CPUs. The & operation can be done with an AND or a TEST, and << would be SHL.

还请记住,访问ASCII字符串时通常应该使用字节操作(即不是 mov%edx,buf2(,%edi,)之类的东西).

Also keep in mind that you typically should be using byte operations when accessing ASCII strings (i.e. not things like mov %edx, buf2(,%edi,)).

这篇关于在程序集x86中将十进制转换为二进制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆