我是汇编新手,正在使用 AT&T 语法在 64 位 linux 中编程。如果我将数字 1 存储在寄存器中,如何将其转换为 ascii 字符“A”?例如:
movl $1, %ebx
addl $64, %ebx
我能否将 64 加 1 得到 65(A 的十进制值),然后以某种方式将其转换为“A”并使用 write 系统调用将其发送到缓冲区?
编辑 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 优于 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
关于linux - 汇编:如何将数字转换为ascii并写入显示缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39501308/