【问题标题】:Assembly GAS Converter hex for binary组装气体转换器十六进制二进制
【发布时间】:2017-03-21 10:04:01
【问题描述】:

您好,我需要在 Assembly GAS 中开发十六进制数到二进制数的转换器。现在我有了这个:

.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

我不知道接下来要做什么。如何在程序中打印我的二进制数。我想我需要一些第二个循环来打印每个二进制四。我现在的这个还可以吗?

【问题讨论】:

    标签: assembly binary hex converter gnu-assembler


    【解决方案1】:

    我现在的这个还可以吗?

    在调试器中运行它并尝试不同的输入,看看 CPU 的最终状态是否与您预期的一样(我有点怀疑它不会完全符合您的预期,代码会随之发生一些变化)。

    如何在程序中打印我的二进制数。

    对于号码12345 (0x3039),二进制输出为11000000111001。那怎么办?

    (初始化部分)假设您在某个寄存器 r1 中有值。对于 32b 数字 r2 = 0x80000000,将其他一些寄存器 r2 设置为零,最高位除外。

    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 语法折磨自己。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-27
      • 2012-05-28
      • 2014-10-30
      • 2012-06-26
      • 2011-10-11
      • 2016-02-09
      • 2012-11-14
      相关资源
      最近更新 更多