16. Пpоцедуpа получает пpи вызове начальный адpес массива из N*M целых чисел в pегистpах  DS:DX и подсчитывает пpоизведение отpицательных элементов пеpвой стpоки таблицы.
Я долго думал и пытался её реализовать. Но всё выходило через.... как обычно кароче. Тогда я накодил в Паскале эту же прогу
var j,x:integer;
    a:array [1..100,1..100] of integer;
begin
a[1,1]:=-4;
a[1,2]:=-2;
a[1,3]:=-5;
a[1,4]:=3;
a[2,1]:=1;
a[2,2]:=2;
a[2,3]:=3;
a[2,4]:=4;
x:=1;
for j:=1 to 4 do
if a[1,j]<0 then
x:=x*a[1,j];
writeln('x= ',x);
readln;
end.
и попытался IDA её дизассемблировать. Получился очень смутный и нерабочий код.
.code
start:
push    ebp
mov     ebp, esp
add     esp, 0FFFFFFF0h
push    esi
mov     eax, off_40AA9C
mov     byte ptr [eax], 1    ; точно не знаю, но вроде это команда x:=1;
mov     eax, offset dword_408C54
call    sub_405424
mov     dword_40F908, 0FFFFFFFCh  ; -4
mov     dword_40F90C, 0FFFFFFFEh  ; -2
mov     dword_40F910, 0FFFFFFFBh  ; - 5
mov     dword_40F914, 3
mov     dword_40FA98, 1
mov     dword_40FA9C, 2
mov     dword_40FAA0, 3
mov     dword_40FAA4, 4
;for j:=1 to 4 do
mov     esi, 1                      ; делать от 1
mov     edx, 4                        ; до 4
;if a[1,j]<0 then
mov     eax, offset dword_40F908    ; копируем в еах содержимое 40F908 (a[1,j])
telo_cikla:                           
test    eax, eax                    ; проверяем равен ли eax нулю
jge     short noshow             ; если больше или равно нулю, то переходим на loc_4091B5( когда условие не выпонилось)
;x:=x*a[1,j]
imul    esi, eax                    ; иначе умножаем esi на ecx
; этого в паскале не видно, но нужно, здесь мы уменьшаем счетчик цикла и (переменная j)  и меняем элемент массива - ну типо вначале первый потом второй и тп
noshow: 
add     eax, 4                        ; eax+4 (таким образом мы смотрим массив, по элементам)
dec     edx                            ;edx -1 (щетчик цикла)
jnz     short telo_cikla            ;если еdx не равно нулю то переходим на loc_4091AC - продолжаем цикл
; иначе
;writeln('x= ',x);
; вызов writeln  разлагается на два вызова writeln вначале вывадим x а затем наше значение
;writeln('x= ')
mov     eax, off_40A9F0                ;какой-то параметр функции, думаю говорит о том что нужно выводить данные на новой строке    
mov     edx, offset dword_4091F8    ;символ x
call    sub_404A24                    ; вызов функции writeln
mov     edx, esi                    ; непосредственно значение x, как видим без доп параметра, значет будем печатать не с новой строки, а продолжим на старой в 
; результате x=40, 40 - это к примеру взял
;readln; тут незнаю замороченный вызов readln.
call    sub_4036C4            
call    sub_4036F0
call    sub_402DDC
mov     eax, off_40AA5C
call    sub_40340C
call    sub_402DDC
pop     esi
call    sub_404518
end start
Вот и пробую создать рабочий вариант. Помогите кто сможет.