2016-11-07 18 views
0

Привет, мне нужно разработать конвертер шестнадцатеричного числа в двоичное число в Assembly GAS. Теперь у меня есть следующее:Assembly GAS Converter hex для двоичного кода

.align 32 

SYSEXIT = 1 
SYSREAD = 3 
SYSWRITE = 4 
STDOUT = 1 
EXIT_SUCCESS = 0 
Input_SIZE = 10 

.bss 
.lcomm Input, Input_SIZE 

.data 

msg: .ascii "Give hex number:\n" 
msg_len = . - msg 

newline: .ascii "\n" 
    newline_len = . - newline 

.text 
.global _start 

_start: 

mov $SYSWRITE, %eax 
mov $STDOUT, %ebx 
mov $msg, %ecx 
mov $msg_len, %edx 
int $0x80 

mov $SYSREAD, %eax 
mov $STDOUT, %ebx 
mov $Input, %ecx 
mov $Input_SIZE, %edx 
int $0x80 

    movl %eax, %edi 
    movl %eax, %edx  
    dec %edx 


loop1: 
cmpl $1, %edx 
je loop1_exit 
movb Input(,%edx,1), %al 


      cmpb 0x00, %al 
      jl number 
      cmpb 0x41, %al 
      jg big_char 
      cmpb 0x46, %al 
      jl big_char 
      cmpb 0x61, %al 
      jg low_char 
      cmpb 0x66, %al 
      jl low_char 

jmp loop1 

number: 
    sub $'0', %al 
big_char: 
    cmpb $'a', %al 
    jae low_char 
    sub $'A', %al 
    add $10, %al 

low_char: 
    sub $'a', %al 
    add $10, %al 

loop1_exit: 
movl $SYSWRITE, %eax 
    movl $STDOUT, %ebx 
    movl $newline, %ecx 
    movl $newline_len, %edx 
    int $0x80 


    movl $SYSEXIT, %eax 
    movl $EXIT_SUCCESS, %ebx 
    int $0x80 

И у меня нет раллий идеи, что делать дальше. Как напечатать мой двоичный номер в программе. Мне кажется, мне нужен второй цикл для печати каждого двоичного кода. Это то, что у меня сейчас, хорошо?

ответ

0

Это то, что у меня сейчас, в порядке?

запустить его в отладчике и попробовать различные входы, увидеть, если результирующее состояние процессора, как вы ожидали (у меня есть какие-то подозрения, это будет не совсем то, что вы ожидаете, и некоторые изменения в коде будут следовать) ,

Как напечатать мое двоичное число в программе.

Для числа 12345 (0x3039) двоичный выход 11000000111001. Так как?

(init часть) Предположим, что у вас есть значение в каком-либо регистре r1. Установите другой регистр r2 в ноль, кроме самого высокого бита, для чисел 32b r2 = 0x80000000.

to_binary_loop: 
    test r1,r2 ; does bitwise AND, discards result, sets up flags 
    output(zero_flag ? '0' : '1') 
    shr r2,1 ; moves the bit to right by 1 position 
    jnz to_binary_loop ; loop till all bits were processed 

Это будет отображать также начальные нули для полного двоичного выхода 32b, как 00000000000000000011000000111001. Чтобы избежать этого, вы можете поставить еще один цикл впереди первого:

to_binary_skip_leading_zeroes: 
    test r1,r2 
    jnz to_binary_found_leading_one 
    shr r2,1 ; next bit 
    jnz to_binary_skip_leading_zeroes 
    ; no "1" bit found in r1, enforce at least single 0 to display 
    mov r2,1 
to_binary_found_leading_one: 

Это output(zero_flag ? '0' : '1') .. Я бы лично написать как:

; somewhere defined (can be even in .text near the loop, read-only usage) 
bin_digit: .ascii "01" 

    ; in init of loop 
    xor r3,r3 ; pick one of eax,ebx,ecx,edx (spare one), set to zero 

    ; during loop after "test r1,r2" 
    setnz r3_byte_part 
    mov bin_digit(r3),al ; al = '0' (ZF=1) or '1' (ZF=0) 
    ; output char in "al" 

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