【问题标题】:Converting decimal to binary in assembly x86在汇编 x86 中将十进制转换为二进制
【发布时间】:2014-05-24 05:10:31
【问题描述】:

我正在尝试将十进制转换为二进制转换器,对于某些数字它可以工作,而对于其他数字则不能。 0 - 8 个数字可以正常工作,但是当我输入 9 时它显示 101。 我已经尝试修复此代码几个小时了,但我找不到它有什么问题。

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

【问题讨论】:

    标签: assembly binary decimal converter


    【解决方案1】:

    您的代码可以大大简化(更简单的代码通常意味着更容易发现任何错误)。下面是一个更简单的方法的概要(我会留给你在 x86 程序集中实现它):

    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&amp; 操作可以使用ANDTEST 来完成,而&lt;&lt; 将是SHL

    另外请记住,在访问 ASCII 字符串时通常应该使用字节操作(即,不是像 mov %edx, buf2(,%edi,) 这样的东西)。

    【讨论】:

    • 在 asm 版本中,可以利用 shift 将 MSB 写入进位标志这一事实。
    • ... 然后是 mov reg, '0' / adc reg, 0 而不是实际的 CMOV 或要选择的分支。
    猜你喜欢
    • 2022-11-14
    • 2014-07-20
    • 2016-10-16
    • 2015-06-02
    • 2015-02-04
    • 1970-01-01
    • 2012-06-02
    • 2012-04-02
    • 1970-01-01
    相关资源
    最近更新 更多