Другие языки программирования и технологии

помощь в выводе строк матрицы в ассемблере.

Нужно вывести строки матрицы с четным первым элементом задом наперед. В отладчике, вроде, ошибка есть в строке присвоения элемента массива переменной. В чем суть ошибки и как исправить не понятно.

.386

.model flat, stdcall

option casemap :none ; case sensitive

include D:\masm32\include\windows.inc

include D:\masm32\include\masm32.inc

include D:\masm32\include\kernel32.inc

include D:\masm32\include\user32.inc

include D:\masm32\include\debug.inc

includelib D:\masm32\lib\user32.lib

includelib D:\masm32\lib\masm32.lib

includelib D:\masm32\lib\kernel32.lib

includelib D:\masm32\lib\debug.lib

include D:\masm32\include\fpu.inc

include D:\masm32\include\msvcrt.inc

includelib D:\masm32\lib\msvcrt.lib

include D:\masm32\macros\macros.asm

includelib D:\masm32\lib\fpu.lib

.data

b dd 100,34,11,24,12,54,16,9,12,19,72,1,14,121,61,22,3,26,5,37

fm db '%d',0

tpt db '%d, ',0

Numbers dd ?

Output dd ?

Buffer db ?

string1 dd ?

buf dd ?

e db ?

jump db 13,10

pr61 db "________End_________"

tbuf dd ?

lines dd 4

columns dd 5

amount dd ?

.code

sturt:

invoke GetStdHandle, STD_OUTPUT_HANDLE

mov Output, eax

mov ebx,0

mov esi,0

mov ecx,0

check:

mov esi,0

mov eax,columns

mov edx,3

imul edx

mov amount,eax ;получение адреса последнего элемента строки

mov eax,b[ebx][esi]

mov edx,0

push ecx

test eax,1

jnp m3

print_lines:

mov esi,amount

mov eax,b[ebx][esi] ;здесь в отладчике ошибка

mov buf,eax

push edx

push ebx

push esi

invoke wsprintf, addr string1,addr fm,dword PTR buf

invoke crt_printf, ADDR tpt, buf

pop esi

pop ebx

pop edx

inc edx

mov eax,amount

sub eax,4 ;движение к первому числу в строке

mov amount,eax

cmp edx,columns

jl print_lines

m3:

invoke WriteConsoleA, Output, addr jump, SIZEOF jump, addr Numbers,0

pop ecx

inc ecx

mov eax,columns

mov edx,4

imul edx

add ebx,eax

cmp ecx,lines

jl check

invoke WriteConsoleA, Output, addr jump, SIZEOF jump, addr Numbers,0

invoke WriteConsoleA, Output, addr pr61, SIZEOF pr61, addr Numbers,0

invoke crt__getch

invoke crt_exit,0

end sturt
Не понятно, зачем вы используете функции WriteConsoleA и wsprintf, если у вас подключена библиотека msvcrt. Её функция crt_printf прекрасно самостоятельно преобразует числа в их символьные представления.
jnp - это проверка не той чётности, о которой вы думаете.

Скорректированная ваша программа (элемент 72 в массиве заменён на 73, чтобы наглядно показать, что программа выводит задом наперёд не все строки, а только те, что требуются по условию) :

.386
.model flat, stdcall
option casemap :none

include D:\masm32\include\windows.inc
include D:\masm32\include\msvcrt.inc

includelib D:\masm32\lib\msvcrt.lib

.data
  b dd 100,34,11,24,12,54,16,9,12,19,73,1,14,121,61,22,3,26,5,37
  lines dd 4
  columns dd 5

  fm db '%4d' ,0
  pr61 db "________End_________", 0
  jump db 13, 10, 0

.code
start:
    xor ebx, ebx
    mov ecx, lines
RowsLoop:
    push ecx
    xor esi, esi
    mov edi, 1
    mov ecx, columns
    test b[ebx][esi], 1
    jnz @F
    neg edi
    add esi, ecx
    dec esi
@@:
    push ecx
    invoke crt_printf, addr fm, b[ebx][esi*4]
    add esi, edi
    pop ecx
    loop @B
    mov eax, columns
    shl eax, 2
    add ebx, eax
    invoke crt_printf, addr jump
    pop ecx
    loop RowsLoop

    invoke crt_printf, addr pr61
    invoke crt__getch
    invoke crt_exit, NULL

    end start

Jahongir Murtazo O`g`li
Jahongir Murtazo O`g`li
51 590
Лучший ответ
1) я бы посмотрел чему равны EBX и ESI и скорее всего там будет вылет за границы памяти
2) странное сохранение ЕСХ, уберите его, а там где возможна его модификация, сохраняйте. а то уж больно разлет там у вас сложный, возможно в каком то переходе он не восстанавливается

3) где нужно сохранить несколько регистров в стеке используйте PUSHA/POPA (1 байт на команду)
Андрей Сырбул
Андрей Сырбул
72 546
Валера Подвышеный 1)Следил за ними, вроде изменяются правильно. ESI, правда, после перехода в m3 принимает максимальное значение, но она там не нужна и после условного перехода снова обнуляется.
2) Просто убирал. Сохранял в переменной. Результат не изменился вообще.

3)Тоже абсолютно не меняют результат.

Похожие вопросы