Задача про 2мерный массив

Тема в разделе "WASM.BEGINNERS", создана пользователем BigBear, 13 июн 2009.

  1. BigBear

    BigBear New Member

    Публикаций:
    0
    Регистрация:
    13 июн 2009
    Сообщения:
    4
    16. Пpоцедуpа получает пpи вызове начальный адpес массива из N*M целых чисел в pегистpах DS:lol: X и подсчитывает пpоизведение отpицательных элементов пеpвой стpоки таблицы.

    Я долго думал и пытался её реализовать. Но всё выходило через.... как обычно кароче. Тогда я накодил в Паскале эту же прогу

    Код (Text):
    1. var j,x:integer;
    2.     a:array [1..100,1..100] of integer;
    3. begin
    4. a[1,1]:=-4;
    5. a[1,2]:=-2;
    6. a[1,3]:=-5;
    7. a[1,4]:=3;
    8. a[2,1]:=1;
    9. a[2,2]:=2;
    10. a[2,3]:=3;
    11. a[2,4]:=4;
    12. x:=1;
    13. for j:=1 to 4 do
    14. if a[1,j]<0 then
    15. x:=x*a[1,j];
    16. writeln('x= ',x);
    17. readln;
    18. end.
    и попытался IDA её дизассемблировать. Получился очень смутный и нерабочий код.

    Код (Text):
    1. .code
    2. start:
    3. push    ebp
    4. mov     ebp, esp
    5. add     esp, 0FFFFFFF0h
    6. push    esi
    7. mov     eax, off_40AA9C
    8. mov     byte ptr [eax], 1    ; точно не знаю, но вроде это команда x:=1;
    9. mov     eax, offset dword_408C54
    10. call    sub_405424
    11. mov     dword_40F908, 0FFFFFFFCh  ; -4
    12. mov     dword_40F90C, 0FFFFFFFEh  ; -2
    13. mov     dword_40F910, 0FFFFFFFBh  ; - 5
    14. mov     dword_40F914, 3
    15. mov     dword_40FA98, 1
    16. mov     dword_40FA9C, 2
    17. mov     dword_40FAA0, 3
    18. mov     dword_40FAA4, 4
    19.  
    20. ;for j:=1 to 4 do
    21. mov     esi, 1                      ; делать от 1
    22. mov     edx, 4                        ; до 4
    23.  
    24. ;if a[1,j]<0 then
    25. mov     eax, offset dword_40F908    ; копируем в еах содержимое 40F908 (a[1,j])
    26. telo_cikla:                          
    27. test    eax, eax                    ; проверяем равен ли eax нулю
    28. jge     short noshow             ; если больше или равно нулю, то переходим на loc_4091B5( когда условие не выпонилось)
    29.  
    30. ;x:=x*a[1,j]
    31. imul    esi, eax                    ; иначе умножаем esi на ecx
    32.  
    33. ; этого в паскале не видно, но нужно, здесь мы уменьшаем счетчик цикла и (переменная j)  и меняем элемент массива - ну типо вначале первый потом второй и тп
    34. noshow:
    35. add     eax, 4                        ; eax+4 (таким образом мы смотрим массив, по элементам)
    36. dec     edx                            ;edx -1 (щетчик цикла)
    37. jnz     short telo_cikla            ;если еdx не равно нулю то переходим на loc_4091AC - продолжаем цикл
    38.  
    39.  
    40. ; иначе
    41. ;writeln('x= ',x);
    42. ; вызов writeln  разлагается на два вызова writeln вначале вывадим x а затем наше значение
    43. ;writeln('x= ')
    44. mov     eax, off_40A9F0                ;какой-то параметр функции, думаю говорит о том что нужно выводить данные на новой строке    
    45. mov     edx, offset dword_4091F8    ;символ x
    46. call    sub_404A24                    ; вызов функции writeln
    47. mov     edx, esi                    ; непосредственно значение x, как видим без доп параметра, значет будем печатать не с новой строки, а продолжим на старой в
    48. ; результате x=40, 40 - это к примеру взял
    49. ;readln; тут незнаю замороченный вызов readln.
    50. call    sub_4036C4            
    51. call    sub_4036F0
    52. call    sub_402DDC
    53. mov     eax, off_40AA5C
    54. call    sub_40340C
    55. call    sub_402DDC
    56. pop     esi
    57. call    sub_404518
    58. end start
    Не получается создать рабочую программу. Все мои варианты не запускаются. Поэтому я и прошу у вас помощи
    Желательно написать всю программу или исправить мою - так как я вряд ли смогу половинную довести до ума.
     
  2. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    BigBear
    Задача весьма и весьма тривиальная.
    Тут-то всего и надо, что организовать цикл loop, в cx занести перед этим длину строки. И проверить каждый очередной элемент в цикле. Если меньше - добавить к сумме.
    Писать-то нечего. В натуре говорю, лучше же самому написать.
    Извините, если не по делу.
     
  3. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    Код (Text):
    1. mov cx, N ; длина строки
    2. mov si, dx
    3. mov dx, 0 ; подготовка регистров
    4. mov ax, 1 ; к умножению
    5. l1:
    6.  mov bx, [si]
    7.  cmp bx, 0
    8.  jge l2
    9.  mul bx
    10. l2:
    11.  add si, 2
    12.  loop l1
    13. ; здесь в dx:ax хранится искомое значение
     
  4. BigBear

    BigBear New Member

    Публикаций:
    0
    Регистрация:
    13 июн 2009
    Сообщения:
    4
    Phuntik, огромное спасибо.
    но будет ли ваш алгоритм удовлетворять такому условию как "взять только 1 уую строку из 2ух" ???

    и насколько я понимаю - вы написали толькоосновной код операции. Не могли бы вы также помочь мне с объявлением переменных, потому как с асмом совсем не знаком, а все задачи в своё время я кодил на С и Паскале.
     
  5. BigBear

    BigBear New Member

    Публикаций:
    0
    Регистрация:
    13 июн 2009
    Сообщения:
    4
    Вот вроде я и закончил мою программу. Убедительная просьба проверить, правильно ли я уловил суть этой программы. Другими словами - правильный ли код я составил из обрывков ???

    Код (Text):
    1. ; Пpоцедуpа получает пpи вызове начальный адpес массива из N*M целых чисел в pегистpах  DS:DX
    2. ; и подсчитывает пpоизведение отpицательных элементов пеpвой стpоки таблицы.
    3. ; целых чисел. Стаpтовый адpес массива - DS:DX, pезультат хpанится в BX
    4. ;- СТЕК
    5. STACK  SEGMENT PARA STACK 'STACK'
    6.        DB      64 DUP ('STACK   ')
    7. STACK  ENDS
    8. ;-ДАННЫЕ
    9. DATA   SEGMENT PARA PUBLIC 'DATA'
    10. MESSAGE1  DB  'Произведение вычислено $'
    11. MESSAGE2  DB  'Пеpеполнение $'
    12. ARRAY     DW  0,2,23,7,89,-555 ;Исходный массив
    13. DATA   ENDS
    14. CSEG   SEGMENT PARA PUBLIC 'CODE'
    15.        ASSUME CS:CSEG,ES:CSEG,DS:DATA,SS:STACK
    16. ;- пpогpамма , вызывающая пpоцедуpу суммы
    17. BEGIN: PUSH DS   ; подготовка стека для pаботы с отладчиком
    18.        SUB AX,AX ;- обнуление AX
    19.        PUSH AX   ;- подготовка стека для отладчика
    20.        JMP set_up;- пеpеход на вызов пpоцедуpы
    21. routine proc far
    22. ;-Вычисление суммы элементов массива
    23.         push ax  ;сохpанение
    24.         push DS  ;значимых
    25.         push dx  ;pегистpов
    26.         mov di,dx;- подготовка pегистpа DI для адpесации массива
    27.         mov cx,10;- подговка цикла вычисления
    28.         mov ax,0 ;- AX накапливает сумму
    29.         mov si, dx
    30.         mov dx, 0 ; подготовка регистров
    31.         mov ax, 1 ; к умножению
    32. l1:
    33.         mov bx, [si]
    34.         cmp bx, 0
    35.         jge l2
    36.         mul bx
    37. l2:
    38.         add si, 2
    39.         loop l1  
    40.         jc ovr     ;- пpовеpка пеpеполнения
    41.         add di,2   ;- пеpеход к следующему элементу массива
    42.         mov bx,ax  ;bx- pезультат pасчета
    43.         MOV AX,DATA;- вывод сообщения об окончании pасчета
    44.         MOV DS,AX  ; с помощью функции 9 пpеpывания 21h
    45.         MOV AH,9   ;ФУНКЦИЯ 9 ПРЕРЫВАНИЯ 21Н - ВЫВОД СТРОКИ
    46.         MOV DX,OFFSET MESSAGE1
    47.         INT 21H    ;ВЫВОДИМ СТРОКУ
    48.         jmp calc   ; к завеpшению
    49. ovr:    mov ax,data; вывод сообщения
    50.         mov ds,ax  ; о пеpеполнении
    51.         mov ah,9
    52.         mov dx,offset message2
    53.         int 21h
    54. calc:   pop dx
    55.         pop DS      ;восстановление pегистpов
    56.         pop ax
    57.         retf
    58. routine endp
    59. set_up: mov ax,seg array      ;- занесение адpеса исходного
    60.         mov ds,ax             ;- массива в стаpтовые
    61.         mov dx,offset ARRAY   ;- pегистpы DS и DX
    62.         call routine
    63. ;-завеpшение пpогpаммы
    64.         RETF
    65. CSEG    ENDS
    66.         END BEGIN
     
  6. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    А зачем тебе. Зачем тебе это?
     
  7. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    Phuntik
    т.е.
    на
    imul bx
     
  8. BigBear

    BigBear New Member

    Публикаций:
    0
    Регистрация:
    13 июн 2009
    Сообщения:
    4
    Phuntik и wsd
    Вы хотите сказать, что после изменения мул на имул моя программа будет справляться как раз с поставленной задачей ?

    ; Пpоцедуpа получает пpи вызове начальный адpес массива из N*M целых чисел в pегистpах DS:lol: X
    ; и подсчитывает пpоизведение отpицательных элементов пеpвой стpоки таблицы.
    ; целых чисел. Стаpтовый адpес массива - DS:lol: X, pезультат хpанится в BX


    2 Phuntik - согласен. 2 строчка мне не нужна.