我刚开始学习 NASM,我正在做第一个涉及文本文件中的矩阵的程序。该文件包含一个 N*N 矩阵,其中第一行包含 N,其他行每行包含矩阵的一行。为了开始完成我更大的任务,我借用了一些代码,它逐行读取文件并将每一行输出到控制台。
我打算读取第一行,将其从字符串转换为整数,将其移动到我将用作计数器的寄存器,然后打印出数组的许多行。我想即使 N=7 并且我在文件的第一行摆弄说 3,如果我打印了 3 行,那么它就可以工作!然而,这并没有奏效。我让它总是打印出一行,这表明我读入并转换为 int 的数字没有正确转换。我尝试在转换后输出此数字,但尝试这样做会导致段错误,令我惊讶!
这是我在 Linux 下的 NASM 代码:
; this program demonstrates how to open files for reading
; It reads a text file line by line and displays it on the screen
extern fopen
extern fgets
extern fclose
extern printf
extern exit
global main
segment .data
readmode: db "r",0
filename: db "hw6_1.dat",0 ; filename to open
error1: db "Cannot open file",10,0
format_1: db "%d",0
segment .bss
buflen: equ 256 ; buffer length
buffer: resd buflen ; input buffer
segment .text
main: pusha
; OPENING FILE FOR READING
push readmode ; 1- push pointer to openmode
push filename ; 2- push pointer to filename
call fopen ; fopen retuns a filehandle in eax
add esp, 8 ; or 0 if it cannot open the file
cmp eax, 0
jnz .L1
push error1 ; report an error and exit
call printf
add esp, 4
jmp .L4
; READING FROM FILE
.L1: mov ebx, eax ; save filepointer of opened file in ebx
; Get first line and pass to ecx
push ebx
push dword buflen
push buffer
call fgets
add esp, 12
cmp eax, 0
je .L3
;convert string -> numeric
push buffer
call parseInt
mov ecx, eax
.L2:
;debug
push ecx
push format_1
call printf
add esp, 8
push ebx ; 1- push filehandle for fgets
push dword buflen ; 2- push max number of read chars
push buffer ; 3- push pointer to text buffer
call fgets ; get a line of text
add esp, 12 ; clean up the stack
cmp eax, 0 ; eax=0 in case of error or EOF
je .L3
push buffer ; output the read string
call printf
add esp, 4 ; clean up the stack
dec ecx
cmp ecx, 0
jg .L2
;CLOSING FILE
.L3: push ebx ; push filehandle
call fclose ; close file
add esp, 4 ; clean up stack
.L4: popa
call exit
parseInt:
push ebp
mov ebp, esp
push ebx
push esi
mov esi, [ebp+8] ; esi points to the string
xor eax, eax ; clear the accumulator
.I1 cmp byte [esi], 0 ; end of string?
je .I2
mov ebx, 10
mul ebx ; eax *= 10
xor ebx, ebx
mov bl, [esi] ; bl = character
sub bl, 48 ; ASCII conversion
add eax, ebx
inc esi
jmp .I1
.I2: pop esi
pop ebx
pop ebp
ret 4
下面显示了一个示例数据文件,这是我使用的一个:
4
2 45 16 22
17 21 67 29
45 67 97 35
68 34 90 72
我真的不明白这是怎么回事。转换为整数的代码是从 WORKING 程序中借来的,我用来调试的输出代码也是如此。