2016-09-14 30 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有效) –

相關問題