以小尾数保存变量

时间:2017-04-25 10:17:29

标签: assembly x86 x86-64 endianness

我想从文件中读取一个值并将其保存为汇编中的小端。输入文件中的值位于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

0 个答案:

没有答案
相关问题