2015-12-14 5 views
0

Я не могу понять, что мне здесь не хватает. Очевидно, что ошибка начинается с read_matrix, но я не понимаю, почему.Ошибка сборки 'push [ebp + 12] [edi] [esi]'

.386 
.model flat, stdcall 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 

;includem libraria msvcrt.lib, biblioteca.asm si declaram ce functii vrem sa importam 
includelib msvcrt.lib 
extern exit:proc 
extern printf: proc 
extern scanf:proc 
extern fopen:proc 
extern fclose:proc 
extern fscanf:proc 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 

;declaram simbolul start ca public-de acolo incepe executia procramului 
public start 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 

;sectiunile programului, date, respectiv cod 
.data 
operation dd 0 
message db "Introduceti o operatie cu matrici:",10,0 
msgA db "A=",0 
msgB db "B=",0 
msgR db "Rezultat:",0 
format db "%s",0 
format1 db "%d",0 
read_mode db "r",0 
write_mode db "w",0 
fileA dd 0 
fileB dd 0 
rezultat dd 0 
op1 dd "A+B",0 
op2 dd "AB",0 
op3 dd "aA",0 
op4 dd "A-B",0 
op5 dd "detA",0 
matA dd 80 dup(?) 
    dd 80 dup(?) 
nrcolA dd 0 
nrlinA dd 0 
pointerA dd 0 
pointerB dd 0 
pointerR dd 0 
.code 
;functie de afisare mesaj pt introducerea operatiei pe matrici 
afisare proc 
    push ebp 
    mov ebp, esp ; pregatim stack frame-ul 
    mov eax, [ebp+8] ; citim primul argument de pe stiva 
    push eax 
    call printf 
    add esp,4 
    mov esp, ebp 
    pop ebp 
    ret 4 ; salt inapoi la adresa de return, si curata parametrii de pe stiva 
afisare endp 
;functie de citire a unei operatii pe matici, ulterior folosita pt citire cale fisier 
citire_operation_file proc 
    push ebp 
    mov ebp, esp ; pregatim stack frame-ul 
    mov edi, [ebp+8] ; citim primul argument de pe stiva-format 
    mov esi,[ebp+12];citim al doilea argument de pe stiva-operatie/fisier 
    push esi 
    push edi 
    call scanf 
    add esp,8 
    mov esp, ebp 
    pop ebp 
    ret 8 ; salt inapoi la adresa de return, si curata parametrii de pe stiva 
citire_operation_file endp 
;functie de deschidere a unui fisier 
open_file proc 
    push ebp 
    mov ebp, esp ; pregatim stack frame-ul 
    mov edi, [ebp+8] ; citim primul argument de pe stiva-format 
    mov esi,[ebp+12];citim al doilea argument de pe stiva-operatie/fisier 
    push esi 
    push edi 
    call fopen 
    add esp,8 
    mov esp, ebp 
    pop ebp 
    ret 8 ; salt inapoi la adresa de return, si curata parametrii de pe stiva 
open_file endp 
close_file proc 
    push ebp 
    mov ebp, esp ; pregatim stack frame-ul 
    mov edi, [ebp+8] ; citim primul argument de pe stiva-format 
    push edi 
    call fclose 
    add esp,4 
    mov esp, ebp 
    pop ebp 
    ret 4 ; salt inapoi la adresa de return, si curata parametrii de pe stiva 
close_file endp 
read_matrix proc 
     push ebp 
     mov ebp, esp ; pregatim stack frame-ul 
     ;[ebp+8]=pointerA,[ebp+12]=matA,[ebp+16]=nrcol,[ebp+20]=nrlin,[ebp+24]=format 
     ;citesc nr de linii pt matricea 
     push [ebp+20] 
     push[ebp+24] 
     push [ebp+8] 
     call fscanf 
     add esp,12 
     ;citesc nr de coloane pt matrice 
     push [ebp+16] 
     push[ebp+24] 
     push[ebp+8] 
     call fscanf 
     add esp,12 
     ;citesc matricea 
     ;parcurg cu edi nr de linii,initial acesta este 0 
     mov edi,0 
     et_loop: 
      cmp edi,[ebp+20] 
      ja urm 
      ;parcurg cu esi nr de coloane,initial acesta este 0 
      mov esi,0 
       et_loop1: 
       cmp esi,[ebp+16] 
       ja urm1 
       push [ebp+12][edi][esi] 
       push [ebp+24] 
       push [ebp+8] 
       call fscanf 
       add esp,12 
       inc esi 
       loop et_loop1 
       urm1: 
       inc edi 
     loop et_loop 
     urm: 
     mov esp, ebp 
     pop ebp 
     ret 20; salt inapoi la adresa de return, si curata parametrii de pe stiva 
read_matrix endp 
start: 
      ;afisez de afisare a unei operatii cu matrici 
      push offset message 
      call afisare 
      ;apelez funtie de citire a unei operatii cu matrici 
      push offset operation 
      push offset format 
      call citire_operation_file 
      ;afisez mesaj de introducere cale fisier pt matricea A 
      push offset msgA 
      call afisare 
      ;citesc calea fisieruli pt matricea A 
      push offset fileA 
      push offset format 
      call citire_operation_file 
      ;deschid fisierul pt matricea A 
      push offset read_mode 
      push offset fileA 
      call open_file 
      mov pointerA,eax 
      ;citesc matricea A 
      push offset format1 
      push offset nrlinA 
      push offset nrcolA 
      push offset matA 
      push pointerA 
      call read_matrix 
      ;afisez mesaj de introducere cale fisier pt matricea B si retin pe stiva pointerul de fisier 
      push offset msgB 
      call afisare 
      ;citesc calea fisierului pt matricea B 
      push offset fileB 
      push offset format 
      call citire_operation_file 
      ;deschid fisierul pt matricea B si retin pe sitiva pointerul de fisier 
      push offset write_mode 
      push offset fileB 
      call open_file 
      mov pointerB,eax  
      ;afisez mesaj de introducere cale fisier pt rezultat si retin pe stiva pointerul de fisier 
      push offset msgR 
      call afisare 
      ;citesc calea fisierului pt rezultat 
      push offset rezultat 
      push offset format 
      call citire_operation_file 
      ;deschid fisierul pt rezultat si retin pe sitiva pointerul de fisier 
      push offset write_mode 
      push offset fileB 
      call open_file 
      mov pointerR,eax 
      ;inchid fisierul pt matricea B 
      push pointerB 
      call close_file 
      ;inchid fisierul pt matricea A 
      push pointerA 
      call close_file 
      ;inchid fisierul pt rezultat 
      push pointerR 
      call close_file 
      ;terminarea programului 
      push 0 
      call exit 
end start 

Ассемблер дает мне ошибку на этой линии:

push [ebp+12][edi][esi] 

Но почему это ошибка? Синтаксис мне кажется подходящим.

+0

Вы должны быть более конкретными. Почему вы считаете, что это не работает? Как вы ожидаете, что он будет себя вести? Что это на самом деле? что ты уже испробовал? –

+0

Есть ли сообщение об ошибке, или что такое ошибка? –

+0

Кажется, здесь «push [ebp + 12] [edi] [esi]». Но почему? Потому что синтаксис выглядит нормально. – user5642508

ответ

2

Вы принимаете сообщение об ошибке, поскольку нотация [ebp+12][edi][esi] недействительна. Честно говоря, я не совсем уверен, что вы собираетесь с этим делать. Вот способы PUSH могут быть использованы:

Registers: 
    PUSH AX 
    PUSH EAX 
    PUSH RAX 

Immediate: 
    PUSH 0xFFFF 
    PUSH 0xFFFFFFFF 
    PUSH 0xFFFFFFFFFFFFFFFF 

Indirect (Memory): 
    PUSHW [BX] ;16 bits - I don't believe an 8 bit push is permitted. 
    PUSHL [BX] ;32 bits 

Использование AT & T синтаксис некоторых это может быть яснее. Например, push $0xffff для немедленного нажатия или push 0x1234 для вывода содержимого памяти.

С помощью косвенных или импульсов памяти вы можете использовать другие регистры для их адресации. Вы можете найти ссылку, например, this.

Обратите внимание, что некоторые из этих может потребоваться уточнение, так как я говорю из памяти. Я не думаю, что когда-либо использовал PUSH содержание адреса памяти.

3

Как сказал Дэвид Хольцер и Майкл Пётч, [ebp+12][edi][esi] не является допустимым режимом адресации. Если бы это был действительный режим адресации, он был бы таким же, как [ebp+12+edi+esi], который не то, что вы хотите. Вы пытаетесь нажать адрес элемента матрицы, и вычисление адреса значительно сложнее.

Вам необходимо заменить его кодом, который вычисляет правильный адрес. Что-то вроде:

mov eax, edi   ; row 
imul eax, [ebp+16] ; row * nrcol 
add eax, esi   ; row * nrcol + col 
mov edx, [ebp+12]  ; matrix address 
lea eax, [edx+eax*4] ; element address 
push eax 

Также следующий код, вероятно, не делать то, что вы собираетесь его:

matA dd 80 dup(?) 
    dd 80 dup(?) 

Это выделяет пространство для матрицы 160 элементов, а не матрицы 6400 элементов (80х80). Если вы хотите использовать более поздние версии:

matA dd 80*80 dup (?)