汇编:如何将数字转换为ascii并写入显示缓冲区

时间:2016-09-14 23:55:37

标签: linux assembly x86-64 gas att

我是汇编的新手,并且使用AT& T语法在linux 64位编程。如果我将数字1存储在寄存器中,我该如何将其转换为ascii字符" A"?例如:

movl $1, %ebx
addl $64, %ebx

我可以添加64到1来制作65(A的十进制值),然后以某种方式将其转换为" A"并使用write system调用将其发送到缓冲区?

编辑1:在此处发布我的程序代码。

.section .data

message:
        .long 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

length:
        .long 10

.section .text

.globl _start

_start:

xorq %rdi, %rdi  
xorq %rax, %rax  
xorq %rbx, %rbx  
xorq %rcx, %rcx                  
xorq %rdx, %rdx  
movl length, %edx

loop:

        cmpl %ecx, %edx                 
        je loop_end                     
        movl message(,%rdi,4), %eax     
        addl $64, %eax                  
        pushq %rax                      
        incq %rdi                       
        incq %rcx                       
        jmp loop                        



loop_end:

        cmpq $0, %rcx                   
        je exit                         
        popq %rbx                       
        pushq %rcx
        movq $1, %rax
        movq $1, %rdi
        movq %rbx, %rsi                 
        movl length, %edx
        syscall                         
        popq %rcx
        decq %rcx
        jmp loop_end

exit:

        movq $60, %rax
        movq $0, %rdi
        syscall

1 个答案:

答案 0 :(得分:0)

我并不完全熟悉AT& T语法,但是你习惯的NASM的反汇编应该足够了。

你应该尽量避免使用所谓的硬编码常量,因为它会使你的程序更难维护,特别是当数百行甚至数千行时。因此;

            section .data       
Values:     db      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 26, 18, 12, 20, 19, 11
V_Size      equ     $ - Values

优于此

    message:
    .long 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

length:
    .long 10

你所做的并没有错,但是这个方法是根据你的计算而不是汇编程序来预测的。正如已经指出的那样,使用完成工作所需的最小数据大小。在这种情况下, char 优于 long

NASM中的此代码

        section .text
    global  _start

_start: xor     ecx, ecx
        push    rcx                 ; Applications default return value
        mov      cl, V_Size
        push    rcx
        mov     ebx, Values
        push    rbx

    Next:
        or      byte [ebx], 64
        inc     ebx
        loop    Next

        pop     rsi
        pop     rdx
        pop     rax
        inc      al
        mov     edi, eax
        syscall

        mov     edi, eax
        dec     edi
        mov     eax, edi
        mov      al, 60
        syscall

        section .data       
Values:     db      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 26, 18, 12, 20, 19, 11
V_Size      equ     $ - Values

将产生

  

ABCDEFGHIJZRLTSK

在“K”之后立即使用命令提示符。

            section .data:
 6000d8 01020304 05060708 090a1a12 0c14130b

        section .text:

<_start>:   These two instructions are idiosyncratic to my style of programming and not
            essential to functionality of program. 

  4000b0:   31 c9                   xor    %ecx,%ecx
  4000b2:   51                      push   %rcx

            Setup RCX & RBX for LOOP instruction

  4000b3:   b1 10                   mov    $0x10,%cl
  4000b5:   51                      push   %rcx                 ARG2 to syscall
  4000b6:   bb d8 00 60 00          mov    $0x6000d8,%ebx
  4000bb:   53                      push   %rbx                 ARG1 to syscall

<Next>:     This conforms to the scope of your objective.

  4000bc:   67 80 0b 40             orb    $0x40,(%ebx)         [ebx] += 'A'
  4000c0:   ff c3                   inc    %ebx
  4000c2:   e2 f8                   loop   4000bc <Next>

            ssize_t write (int fd, const void *buf, size_t count);

  4000c4:   5e                      pop    %rsi                 ARG1 = ASCII Pntr
  4000c5:   5a                      pop    %rdx                 ARG2 = # of chars
  4000c6:   58                      pop    %rax
  4000c7:   fe c0                   inc    %al                  SYS_WRITE
  4000c9:   89 c7                   mov    %eax,%edi            ARG0 = STD_OUT
  4000cb:   0f 05                   syscall

            Epilogue: Again, just a method I use.

  4000cd:   89 c7                   mov    %eax,%edi  
  4000cf:   ff cf                   dec    %edi
  4000d1:   89 f8                   mov    %edi,%eax
  4000d3:   b0 3c                   mov    $0x3c,%al
  4000d5:   0f 05                   syscall