我被一个任务卡住了。
我必须写一个程序,它从文件中读取字符串,按第六列对最后10个字符串进行排序,然后在一个新文件中输出排序后的字符串。
前两列包含带有[1; 20]个字符,则3-5列包含[-100; 100]和第6列包含真实的[-9.99; 9.99].每一部分用';'符号。
输入档案:
48CBC0h ucbe5u F bc6; 6 laY xdU;-62;-29;11;-6.34
AJKCvwHUvmL CjWRl;WQc1 E2wzyTU;3;-20;24;8.26
9jicRCI8S b ; p9m R7iHqOj 9ig h;-93;19;-92;6.18
Xv ;IufLkIUp;-23;-94;76;2.63
A o8P8T 26;Zy J IVg6;-80;-58;-42;-5.96
hlwCw Z8ChU;KX0 w C3 N60 KZV;-94;61;-71;-3.31
Rtqn58 2 l BTWdVgl H;rd U ;9;70;10;8.66
M x91pVZ6UQ Nb;p;-5;-27;74;4.04
rq8s3Gc Bj x 2XG ;8E cTH a ZF VLp2E;-4;21;-89;7.9
ca yfUpVXuC7 ;sXvttLZs4 nqcv 5fTg;-34;-40;14;-5.19
j;yL7 G dG C vR B;70;-89;-87;-9.52
2n 5 O F MMc16; Awcsl2sI;-97;-82;34;1.01
EeLVLB;qR q4i D5q ;70;49;-11;-5.43
nsWW j9;AGBGVXO N;59;97;74;6.22
ou 7vCvBUc;yVW30Jwcv Qtj;18;-10;77;9.38
我试图保存这些行的指针,以及第六列,我没有开始考虑排序函数。
以下是我目前为止所写的内容:
%include 'yasmmac.inc'
org 100h
section .text
start:
mov si, 0x80
mov di, readFile
dec di
mov cl, byte [si]
cmp cl, 01
jg .name
.name:
inc si
mov al, byte [si]
mov byte [di], al
inc di
loop .name
macPutString 'Input name for writing file', crlf, '$'
mov al, 128
mov dx, writeFile
call procGetStr
macNewLine
mov dx, readFile
call procFOpenForReading
jnc .reading
macPutString 'Error occured', crlf, '$'
jmp .end
.reading:
mov [readingD], bx
mov di, pointers
xor dx, dx
dec dx
.whileNotEndOfFile:
push bx
mov bx, numberOfLines
inc word [bx]
pop bx
mov [di], dx
inc di
inc di
.tillLineEnds:
inc dx
call procFGetChar
cmp ax, 0x0
je .readingClose
cmp cl, 0x0a
jne .tillLineEnds
jmp .whileNotEndOfFile
.readingClose:
call procFClose
mov di, pointers
inc word[di]
mov dx, writeFile
call procFCreateOrTruncate
jnc .filter
macPutString 'Error occured', crlf, '$'
jmp .end
.filter:
mov [writingD], bx
push bx
mov bx, numberOfLines
dec word [bx]
cmp word [bx], 0x000a
jl .errorInfo
pop bx
jge .continue
.errorInfo:
pop bx
mov bx, [writingD]
mov cx, 0x0050
mov dx, error
call procFWrite
mov bx, [readingD]
call procFClose
mov bx, [writingD]
call procFClose
jmp .end
.continue:
mov dx, readingFile
call procFOpenForReading
jnc .secondReading
macPutString 'Error occured', crlf, '$'
jmp .pabaiga
.secondReading:
mov [readingD], bx
mov dx, numberOfLines
sub dx, 0x000a
xor cx, cx
mov cx, dx
xor ax, ax
cmp cx, 0x0
jg .skipLines
mov di, sixth
jmp .sixthColumn
.skipLines:
push cx
.skip:
call procFGetChar
cmp cl, 0x0a
jne .skip
pop cx
loop .skipLines
.sixthColumn:
xor si, si
.skipSign:
call procFGetChar
cmp cl, ';'
jne .skipSign
inc si
cmp si, 0x0005
jl .skipSign
.save:
call procFGetChar
cmp ax, 0x0
je .ifNotEnd
cmp cl, 0x0a
je .ifNotEnd
cmp cl, '.'
je .save
mov [di], cl
inc di
jmp .save
.ifNotEnd:
cmp ax, 0x0
je .endReading
jmp .sixthColumn
.endReading:
call procFClose
.end
exit
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%include 'yasmlib.asm'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .data
readingFile:
times 255 db 00
writingFile:
times 255 db 00
readingD:
dw 0000
writingD:
dw 0000
error:
db 'Not enough data', 0x0d, 0x0a, '$'
numberOfLines:
times 128 db 00
pointers:
times 3000 db 00
sixth:
times 20000 db 00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .bss
先谢谢你了。
1条答案
按热度按时间gopyfrb31#
回顾您的工作(最重要的部分)
我在从命令行获取filespec的代码中发现了3个问题:
mov di, readFile
dec di
中的递减,接下来的循环将写入位于 readFile 缓冲区之外的字节!这个构造在汇编编程中是没有意义的。如果条件是greater,那么你跳转到 .name,但是如果条件是not greater,那么你在 .name 中失败。无论如何,你总是在 .name 中运行代码。
loop .name
指令依赖于整个CX寄存器,而您只初始化了它的最低8位(mov cl, byte [si]
)。在 *.阅读 * 中,接下来的代码将递增 numberOfLines 变量:
首先,你可以在一条指令
inc word [numberOfLines]
中完成这一操作,其次,为什么在知道下一行会被找到之前就增加行计数呢?在程序的后面,你会无条件地减少计数。类似的情况也会发生在你存储的第一个指针上:您开始将其赋值为-1,然后在稍后的某个时间点将其无条件地设置为0。在 .continue 中,您在关闭源文件后重新打开它,但您现在使用的是不同的文件规范!
确定文件位置在 readFile 或 readingFile
我在下面提出的替代解决方案将不需要阅读源文件两次。
在 .secondReading 中,您忘记了用于取消引用的方括号。
因此,后面的 .skipLines 将运行很多次迭代!而且由于您隐藏
mov di, sixth
指令的位置,*. sixthColumn * 中的代码将写入DI寄存器恰好指向的任何位置!为什么你要保留这么大的字节数来处理10行呢?多了肯定不是更好!
我的解决方案(如果 * 您仔细研究它,它将非常重要)
提示:20 + 1 + 20 + 1 + 4 + 1 + 4 + 1 + 4 + 1 + 5 + 2 = 64(最长线)
最后10行现在保存在10个64字节缓冲区中。顺序并不重要,因为任务要求您对它们进行排序(使用第6列)。
我很期待看到您将如何排序记录。我个人会将第6列的定点()数字转换为[-999,999]范围内的整数(忽略小数点),并将它们存储在一个字大小的数组中,以备排序。我会使用索引从0到9的数组,而不是包含指针的辅助数组。
第一个数组中的条件交换必须与第二个数组中的无条件交换相匹配。在x86中尝试进行冒泡排序时,在分段错误的答案中可以找到一个很好的冒泡排序,但可以随意使用您喜欢的任何排序算法...
()请注意以下行:
rq8s3Gc Bj x 2XG ;8E cTH a ZF VLp2E;-4;21;-89;7.9
从以前类似的问答中,我的印象是第6列的数字都是2位数的分数。这一行没有使用“7.90”。要么是你打错了,要么你必须在程序中考虑到这一点。