我是汇编的新手,并且使用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
答案 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