我的汇编语言项目的 x86 代码中出现错误

问题描述 投票:0回答:1

请修复以下代码行中的以下错误。我在 Visual Studio 中使用 x86 代码和 Irvine 文件:

  • 我的程序中的第 98 行出现错误 A2032“寄存器使用无效”

    cmp eax, edx+7 ; Check if the end of the line is reached for the reviewer number
    .

  • 我的代码第 70 行出现错误 MSB3721“命令”ml.exe /c /nologo /Sg /Zi /Fo"Debug\NDProject1.obj" /Fl"Project.lst" /I "c:\Irvine “ /W3 /errorReport:prompt /TaNDProject1.asm” 退出,代码为 1。”

  • 我的代码第 30 行出现错误 A2006“未定义符号:OpenFile”

  • 我的代码第 34 行出现错误 A2006“未定义符号:ReadLine”

附上我的代码:

INCLUDE Irvine32.inc

.DATA
reviewScores DWORD 4 DUP (5 DUP (0)) ; Two-dimensional array to store review scores (4 rows by 5 columns)

movieNames BYTE "A",0, "B",0, "C",0, "D",0, "E",0
filename BYTE "C:\Data\reviews.txt",0
buffer BYTE 200 DUP (?) ; Increase the buffer size to handle larger lines

.CODE
main PROC
    call ReadFromFile       ; Read movie review information from the file
    call CalculateTotalScores  ; Calculate total scores for each movie
    call DisplayReport      ; Display the report with total scores and the movie with the highest total score

    exit
main ENDP

; Procedure to read movie review information from the file
ReadFromFile PROC
    mov edx, OFFSET reviewScores ; Load the address of the array into edx
    mov ecx, 20                ; Total number of lines in the file (4 reviewers x 5 movies)

    mov ebx, 0                 ; ebx will be used to keep track of the current line number
    mov esi, OFFSET filename   ; Load the address of the file name into esi

ReadLoop:
    ; Open the file for reading
    mov edx, 0                ; Clear edx to use it as a flag for reading mode (0 = read)
    call OpenFile  <<<< line 30 >>>>

    ; Read a line from the file
    mov edx, OFFSET buffer    ; Load the address of the buffer into edx
    call ReadLine  <<<< line 34 >>>>

    ; Check if end of file reached
    cmp eax, 0
    je EndOfFile

    ; Parse the line to extract movie review information
    mov eax, OFFSET buffer
    call ParseLine

    ; Store the review score in the array
    mov eax, dword ptr [edx]  ; Load the review score (0-100) into eax
    mov ebx, dword ptr [edx+4]  ; Load the reviewer number (1-4) into ebx
    mov ecx, dword ptr [edx+8]  ; Load the movie number (0-4) into ecx
    mov edi, OFFSET reviewScores
    imul ebx, ebx, 5          ; Calculate the offset for the reviewer's row
    add edi, ebx
    add edi, ecx              ; Calculate the offset for the movie's column
    mov dword ptr [edi * 4], eax ; Store the review score in the array

    inc ebx                  ; Move to the next line
    jmp ReadLoop

EndOfFile:
    ; Close the file
    mov edx, 1               ; Set edx to 1 to use it as a flag for closing the file
    call CloseFile

    ret
ReadFromFile ENDP

; Procedure to parse a line and extract movie review information
ParseLine PROC
    mov edx, eax              ; Store the address of the line in edx

    ; Extract the movie number (0-4) from the line
    movzx ecx, byte ptr [edx] <<<< line 70 >>>> ; Load the first character of the line into ecx
    sub ecx, 'A'              ; Convert movie letter to index (0-4)
    mov [edx+8], ecx          ; Store the movie number in the buffer

    ; Extract the review rating (0-100) from the line
    mov eax, edx
    mov ecx, 0
ScanRating:
    inc eax                   ; Move to the next character in the line
    movzx ebx, byte ptr [eax] ; Load the next character
    cmp ebx, ','              ; Check if it's a comma
    je FoundComma             ; If yes, we found the end of the rating
    imul ecx, ecx, 10         ; Multiply the current rating by 10 to shift it left
    sub ebx, '0'              ; Convert character to numeric value
    add ecx, ebx              ; Add the numeric value to the rating
    jmp ScanRating

FoundComma:
    mov [edx], ecx            ; Store the review rating (0-100) in the buffer

    ; Extract the reviewer number (1-4) from the line
    mov eax, edx
    mov ecx, 0
ScanReviewer:
    inc eax                   ; Move to the next character in the line
    movzx ebx, byte ptr [eax] ; Load the next character
    sub ebx, '0'              ; Convert character to numeric value
    add ecx, ebx              ; Add the numeric value to the reviewer number
    cmp eax, edx+7 <<<< line 98 >>>> ; Check if the end of the line is reached for the reviewer number
    je DoneParsing            ; If yes, we are done parsing the line
    jmp ScanReviewer

DoneParsing:
    mov [edx+4], ecx          ; Store the reviewer number (1-4) in the buffer

    ret
ParseLine ENDP

; Procedure to calculate the total scores for each movie
CalculateTotalScores PROC
    mov edx, OFFSET reviewScores ; Load the address of the array into edx
    mov ebx, 20                  ; Total number of elements in the array (4 reviewers x 5 movies)
    xor ecx, ecx                 ; Initialize ecx to 0 for the total score

CalculateLoop:
    add ecx, dword ptr [edx]    ; Add the current review score to the total score
    add edx, 4                   ; Move to the next element in the array
    loop CalculateLoop

    ret
CalculateTotalScores ENDP

; Procedure to display the report with total scores and the movie with the highest total score
DisplayReport PROC
    mov edx, OFFSET reviewScores ; Load the address of the array into edx
    mov ebx, 0                   ; Initialize ebx to 0 to keep track of the movie with the highest total score
    mov ecx, 0                   ; Initialize ecx to 0 for the highest total score

    ; Calculate the total score for each movie and find the highest total score
    mov edi, 5                   ; Number of movies (5)
    mov esi, OFFSET movieNames   ; Load the address of the array of movie names into esi

CalculateMovieScores:
    push ecx                     ; Save the highest total score on the stack

    ; Calculate the total score for the current movie
    mov eax, edx
    xor ecx, ecx                 ; Initialize ecx to 0 for the total score of the current movie
    mov ebx, 0                   ; Initialize ebx to 0 for the reviewer index

CalculateMovieTotal:
    add ecx, dword ptr [eax]     ; Add the current review score to the total score of the current movie
    add eax, 20                  ; Move to the next movie's review score
    inc ebx                      ; Move to the next reviewer's review score
    cmp ebx, 4                   ; Check if we have processed all reviewers
    jle CalculateMovieTotal      ; If not, calculate the next reviewer's score

    ; Display the total score for the current movie
    pop eax                      ; Restore the highest total score from the stack to eax
    cmp ecx, eax                 ; Compare the current movie's total score with the highest total score
    jle NotHighestScore          ; If the current score is not the highest, skip displaying it

    mov ebx, eax                 ; Update the highest total score with the current movie's total score
    mov esi, OFFSET movieNames   ; Load the address of the array of movie names into esi
    call WriteString             ; Display the movie name
    mov eax, ecx                 ; Load the current movie's total score into eax
    call WriteDec                ; Display the total score
    call Crlf                   ; Move to the next line

NotHighestScore:
    add esi, 4                   ; Move to the next movie name
    dec edi                      ; Move to the next movie
    cmp edi, 0                   ; Check if we have processed all movies
    jg CalculateMovieScores      ; If not, calculate the next movie's score

    ret
DisplayReport ENDP

END main

这是reviews.txt文件:

D,84,2
A,90,3
A,87,4
B,35,4
B,100,1
C,75,1
D,84,1
B,87,2
A,0,2
C,25,2
D,45,3
E,35,3
A,90,1
B,100,3
C,75,3
E,35,1
C,78,4
E,35,2
D,100,4
E,0,4

谢谢你

我尝试了很多事情,但都失败了,真的需要一些帮助。 Errors in code

visual-studio assembly x86 cpu-architecture irvine32
1个回答
0
投票
  • 我的代码第 30 行出现错误 A2006“未定义符号:OpenFile”
  • 我的代码第 34 行出现错误 A2006“未定义符号:ReadLine”

使用

INCLUDE Irvine32.inc
,您无法访问 OpenFileReadLine
然而,该文件确实定义了下一个原型:

打开输入文件原型;以输入模式打开文件
从文件读取原型;从输入文件读取缓冲区


  • 我的程序中的第 98 行出现错误 A2032“寄存器使用无效”
    cmp eax, edx+7 ; Check if the end of the line is reached for the reviewer number

就像@PeterCordes 在评论中所写,

cmp eax, edx+7
指令不可编码。您需要将地址表达式
EDX + 7
放入其自己的寄存器中。
我建议使用以下解决方案,暂时将 EDX 寄存器提高 7,以便可以在
cmp eax, edx
指令中使用:

FoundComma:
    mov   [edx], ecx          ; Store the review rating (0-100) in the buffer
    ADD   EDX, 7              <<<< Temporarily change EDX >>>>
    ; Extract the reviewer number (1-4) from the line
    mov   eax, edx
    XOR   ECX, ECX
ScanReviewer:
    inc   eax                 ; Move to the next character in the line
    movzx ebx, byte ptr [eax] ; Load the next character
    sub   ebx, '0'            ; Convert character to numeric value
    add   ecx, ebx            ; Add the numeric value to the reviewer number
    cmp   eax, EDX            ; Check if the end of the line is reached for the reviewer number
    jne   ScanReviewer        ; If no, we are not done parsing the line
    SUB   EDX, 7              <<<< Restore EDX to what it was before >>>>
    mov   [edx+4], ecx        ; Store the reviewer number (1-4) in the buffer
    ret
ParseLine ENDP
© www.soinside.com 2019 - 2024. All rights reserved.