[英]Assembly: how to convert number into ascii and write to display buffer
我是组装的新手,并且正在以AT&T语法在Linux 64位中进行编程。 如果将数字1存储在寄存器中,如何将其转换为ASCII字符“ A”? 例如:
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
我并不完全熟悉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比长要好
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.