2016-09-14 159 views
0

我是新来的程序集,并且我正在使用ATL & T语法在linux 64位编程。如果我将数字1存储在一个寄存器中,我怎样才能将它转换为ASCII字符“A”?例如:汇编:如何将数字转换为ASCII并写入显示缓冲区

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

我可以添加64到1,使65(A的十进制值),然后以某种方式将其转换为“A”和使用写系统调用发送该到缓冲区?

编辑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 
+0

是的,你甚至可以使用'add $'A',%ebx'使你的代码更具人类可读性,并记录常量的目的。字符*是整数,所以是的,你只是将该字节存储在内存中,并将指针传递给该存储器以“write(0,buf,1)' –

+0

好吧,但是如果我不想使用常量,我会将%ebx寄存器中的$ 65转换为'A'吗?他们的任何操作是否会转化为ascii? – Mic

+0

创建一个临时缓冲区。在其中放置一个字符(65是一个已经表示字符的值)。将缓冲区的地址传递给'sys_write'系统调用。 –

回答

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 

是你做了什么没有错,但该方法在你身上算起,而不是汇编的前提是。正如已经指出的那样,使用完成工作所需的最小数据大小。在这种情况下优于

该代码在NASM

立刻后 “K”
 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

与命令提示。

  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 
+0

为什么使用这种奇怪的未注释的NASM代码来设置系统调用的寄存器?你的SYS_exit(eax = 60)似乎取决于写返回一个正值(而不是错误代码)。所以你可以通过运行'./a.out>/dev/full','./a.out>& - '(close stdout)或者其他任何方式来让你的程序运行带有'eax = 0xFFFFFF3c'的'syscall'使sys_write失败。内核查看整个EAX,而不仅仅是AL,用于系统调用号(x86-64系统调用号当前为'__NR_execveat 322')。哦,我看到你在AT&T disasm输出中有评论,但他们没有解释任何内容。 –

+0

即使您确实希望您的退出状态依赖于write(),编写相同代码的理智方式也只有一半:'lea edi,[rax-1]'/'mov eax,SYS_write'。混淆mov/dec/mov/mov imm没有任何优势。 –

+0

同样,从你之前疯狂的PUSH/POP代码中可以看出零优势和很多混乱。 'xor ecx,ecx' /'mov cl,V_Size'保存一个字节,而MOV r32,imm32只能在V_Size适合8位时使用。 (就像你说的,避免在你的程序中使用硬编码假设!)它也浪费了一条指令,这个指令在任何支持AMD64的CPU上都不止一个代码字节。 [LOOP是一个非常缓慢的指令,你不应该使用。](http://stackoverflow.com/questions/35742570/why-is-the-loop-instruction-slow-couldnt-intel-have-implemented-it有效) –

相关问题