我想从文件中读取一个值并将其保存为汇编中的小端。输入文件中的值位于OCT中。我写了一些我认为应该有用的代码,但不是:/
我的想法: 我当然读了一个ascii,所以我把它加载到缓冲区。然后我将第一个字节从缓冲区加载到寄存器,减去' 0' 0使它成为一个数字而不是字符,并将其添加到bx寄存器。对于每个下一个字节,我做同样的事情,但我首先移动添加之前的位(因为我的值存储在三位,我移动值,3,6,9等)我做了8次然后将它保存到缓冲区。我通过移动我的寄存器的bl部分来执行缓冲,然后将位移动8位(执行3次)。
我的问题是我在终端中遇到垃圾(我尝试在最后显示最终缓冲区)或者无法打开我写入结果的文件。我在调试器中看到,在保存阶段我最终得到负值,但我无法理解为什么。
我的代码:
.data
SYSREAD = 0
SYSWRITE = 1
SYSOPEN = 2
SYSCLOSE = 3
STDOUT = 1
FREAD = 0
FWRITE = 1
SYSEXIT = 60
EXIT_SUCCESS = 0
BUFLEN = 1024
num_in1: .ascii "in.txt\0" # Nazwa pliku musi kończyć się zerowym bajtem
num_in2: .ascii "in2.txt\0"
num_out: .ascii "out.txt\0"
.bss
.comm textin, 1024
.comm textin2, 1024
.comm value1, 512
.comm value2, 512
.comm output, 513
.comm output_not_in_endian, 513
.comm result, 1024
.text
.globl _start
_start:
# clear buffor
mov $512, %rdi
mov $0, %al
clearing:
dec %rdi
mov %al, value1(, %rdi, 1)
cmp $0, %rdi
jg clearing
mov $512, %rdi
clearing2:
dec %rdi
mov %al, value2(, %rdi, 1)
cmp $0, %rdi
jg clearing2
# opening file
mov $SYSOPEN, %rax
mov $num_in1, %rdi
mov $0, %rsi
mov $0, %rdx
syscall
mov %rax, %r10
# read from file
mov $SYSREAD, %rax
mov %r10, %rdi
mov $textin, %rsi
mov $1024, %rdx
syscall
mov %rax, %r8
dec %r8
# closing file
mov $SYSCLOSE, %rax
mov %r10, %rdi
mov $0, %rsi
mov $0, %rdx
syscall
mov $0, %r9
loop:
dec %r8
and $0, %al
mov $0, %rdi
mov textin(, %r8, 1), %al
movq %rax, %rbx
sub $'0', %bl
cmp $0, %r8
jle zapisz
dec %r8
and $0, %rax
mov textin(, %r8, 1), %al
sub $'0', %al
shl $3, %rax
add %rax, %rbx
cmp $0, %r8
jle zapisz
dec %r8
and $0, %rax
mov textin(, %r8, 1), %al
sub $'0', %al
shl $6, %rax
add %rax, %rbx
cmp $0, %r8
jle zapisz
dec %r8
and $0, %rax
mov textin(, %r8, 1), %al
sub $'0', %al
shl $9, %rax
add %rax, %rbx
cmp $0, %r8
jle zapisz
dec %r8
and $0, %rax
mov textin(, %r8, 1), %al
sub $'0', %al
shl $12, %rax
add %rax, %rbx
cmp $0, %r8
jle zapisz
dec %r8
and $0, %rax
mov textin(, %r8, 1), %al
sub $'0', %al
shl $15, %rax
add %rax, %rbx
cmp $0, %r8
jle zapisz
dec %r8
and $0, %rax
mov textin(, %r8, 1), %al
sub $'0', %al
shl $18, %rax
add %rax, %rbx
cmp $0, %r8
jle zapisz
dec %r8
and $0, %rax
mov textin(, %r8, 1), %al
sub $'0', %al
shl $21, %rax
add %rax, %rbx
zapisz:
mov %bl, value1(, %r9,1)
shr $8, %rbx
inc %rdi
inc %r9
cmp $3, %rdi
jl zapisz
cmp $0, %r8
je zapisz1
jmp loop
zapisz1:
# display
mov $SYSWRITE, %rax
mov $STDOUT, %rdi
mov $value1, %rsi
mov $1024, %rdx
syscall
# opening/creating the result file
mov $SYSOPEN, %rax
mov $num_out, %rdi
mov $FWRITE, %rsi
mov $0644, %rdx
syscall
mov %rax, %r8 # file descriptor to r8
# save to file
mov $SYSWRITE, %rax
mov %r8, %rdi
mov $value1, %rsi
mov $1024, %rdx
syscall
# closing file
mov $SYSCLOSE, %rax
mov %r8, %rdi
mov $0, %rsi
mov $0, %rdx
syscall
# ending
mov $SYSEXIT, %rax
mov $EXIT_SUCCESS, %rdi
syscall
编辑:代码运作良好。缓冲区中的数字很好,但是当试图显示它们时,它们会转换为ascii代码。所以我基本上尝试显示字符,例如ascii代码。 3,这是不可读的,最终打印垃圾。
此外,简化版本,使用cl
寄存器移动位(仅片段)
loop:
dec %r8
and $0, %al
mov $0, %rdi
mov $0, %cl
read:
mov textin(, %r8, 1), %al
shl %cl, %rax
add $3, %cl
add %rax, %rbx
cmp $0, %r8
jle zapisz
dec %r8
and $0, %rax
cmp $21, %cl
jle read
zapisz:
mov %bl, value1(, %r9,1)
shr $8, %rbx
inc %rdi
inc %r9
cmp $3, %rdi
jl zapisz
cmp $0, %r8
je zapisz1
jmp loop