Помощь - Поиск - Пользователи - Календарь
Полная версия: интересные программы на Asm
Форум «Всё о Паскале» > Delphi, Assembler и другие языки. > Assembler
doctor
Так вот=)... rolleyes.gif 1. Дан произвольный двумерный массив A(N*M). Найти строку с максимальной суммой элементов.
2. Так же дан массив. Найти максимальный элемент кратный 2 и не кратный 5.
заранее большое спасибо! :thanks:
xds
Решение второй задачи:

.model tiny
.186
locals

;размер массива
N		equ 3
M		equ 4

;значение результата "искомый элемент не найден"
R_NOT_FOUND	equ -32765

;ширина поля при выводе чисел
FIELD_WIDTH	equ 4

.code
.startup
;инициализация и вывод массива	
	call init_array
	lea dx,msg1
	call write_msg
	call write_array
	call new_line

;поиск элемента, удавлетворяющего условию
	mov bx,10
	lea si,a
	mov cx,N*M
	cld
next_elem:
	lodsw
	cmp ax,result	;проверка на "максимальность"
	jle skip_elem
	test al,1	;проверка на чётность (кратность 2)
	jnz skip_elem
	push ax		;провека на кратность 5
	cwd
	idiv bx	
	or dx,dx
	pop ax
	jz skip_elem
	mov result,ax
skip_elem:
	loop next_elem

;вывод результата поиска
	mov ax,result
	cmp ax,R_NOT_FOUND
	je not_found
	push ax		;вывод значения найденного элемента
	lea dx,msg2
	call write_msg
	pop ax
	call write_int
	call new_line
	jmp exit
not_found:
	lea dx,msg3	;вывод сообщения о том, что элемент не найден
	call write_msg
exit:
	mov ax,4C00h
        int 21h

;--- Заполнение массива псевдослучайными числами ---
init_array proc
;инициализация псевдослучайной последовательности
	push es		
	xor ax,ax
	mov es,ax
	mov ax,es:[46Ch]
	pop es
	mov rnd0,ax
	inc ax
	mov rnd,ax

;заполнение массива
	lea di,a
	cld
	mov cx,N*M
@@1:
	mov ax,rnd0	;смещение псевдослучайной последовательности
	mov dx,rnd
	add ax,dx
	mov rnd,ax
	mov rnd0,dx	
	sar ax,9        ;целое число из отрезка [-64, 63]
	stosw
	loop @@1
	ret
init_array endp

;--- Вывод символа ---
;Вход: dl = <код символа>
write_char proc
	mov ah,2
	int 21h
	ret
write_char endp

;--- Вывод сообщения ---
;Вход: dx -> <строка - текст сообщения + '$'>
write_msg proc
	mov ah,9
	int 21h
	ret
write_msg endp

;--- Переход на новую строку ---
new_line proc
	mov dl,13
	call write_char
	mov dl,10
	call write_char
	ret
new_line endp

;--- Вывод целого значения ---
;Вход: ax = <значение>
write_int proc
	push si
	mov bx,ax
	or ax,ax
	jns @@1
	neg ax

;выделение цифр и подсчет их количества (в cx)
@@1:
	xor cx,cx
	mov si,10
@@2:
	inc cx
	xor dx,dx
	div si
	add dl,'0'
	push dx
	or ax,ax
	jnz @@2

;добавление знака "-" перед отрицательными значениями
	or bx,bx
	jns @@3
	inc cx
	mov al,'-'
	push ax

;вывод поля
@@3:
	push cx
	neg cx
	add cx,FIELD_WIDTH
	or cx,cx
	jle @@5
@@4:
	push cx
	mov dl,' '
	call write_char
	pop cx
	loop @@4

;вывод числа
@@5:
	pop cx
@@6:	
	pop dx
	call write_char
	loop @@6
	pop si
	ret
write_int endp

;--- Распечатка массива ---
write_array proc
	lea si,a
	mov dx,N
@@1:
	push dx
	mov cx,M
@@2:
	push cx
	lodsw
	call write_int
	pop cx
	loop @@2
	call new_line
	pop dx
	dec dx
	jnz @@1
	ret
write_array endp

msg1	db 'Данный массив:',13,10,'$'
msg2	db 'Значение искомого элемента: $'
msg3	db 'Не найдено ни одного элемента, удавлетворяющего условию',13,10,'$'

;результат поиска
result	dw R_NOT_FOUND

;массив
a	dw N*M dup(?)

;два последних элемента псевдослучайной последовательности
rnd0	dw ?
rnd	dw ?
	
	end

xds
Решение первой задачи:
.model tiny
.8086
locals

;размер массива
N		equ 10
M		equ 3

;ширина поля при выводе чисел
FIELD_WIDTH	equ 4

.code
.startup
;инициализация и вывод массива	
	call init_array
	lea dx,msg1
	call write_msg
	call write_array
	call new_line

;поиск строки с максимальной суммой элементов
	xor di,di	;di = N - <номер искомой строки>
	mov bx,-32768	;bx = <макс. значение суммы>
	lea si,a
	mov cx,N
next_row:
	push cx
	xor dx,dx	;подсчёт суммы элементов строки
	mov cx,M
next_elem:
	lodsw
	add dx,ax
	loop next_elem
	pop cx
	cmp dx,bx
	jle skip_row
	xchg bx,dx
	mov di,cx
skip_row:
	loop next_row
	neg di		;<номер искомой строки> = N - di
	add di,N

;вывод номера найденной строки
	push di
	lea dx,msg2
	call write_msg
	pop ax
	call write_int
	call new_line

;выход
	mov ax,4C00h
        int 21h

;--- Заполнение массива псевдослучайными числами ---
init_array proc
;инициализация псевдослучайной последовательности
	push es		
	xor ax,ax
	mov es,ax
	mov ax,es:[46Ch]
	pop es
	mov rnd0,ax
	inc ax
	mov rnd,ax

;заполнение массива
	lea di,a
	cld
	mov cx,N*M
@@1:
	mov ax,rnd0	;смещение псевдослучайной последовательности
	mov dx,rnd
	add ax,dx
	mov rnd,ax
	mov rnd0,dx	
	sar ax,9        ;целое число из отрезка [-64, 63]
	stosw
	loop @@1
	ret
init_array endp

;--- Вывод символа ---
;Вход: dl = <код символа>
write_char proc
	mov ah,2
	int 21h
	ret
write_char endp

;--- Вывод сообщения ---
;Вход: dx -> <строка - текст сообщения + '$'>
write_msg proc
	mov ah,9
	int 21h
	ret
write_msg endp

;--- Переход на новую строку ---
new_line proc
	mov dl,13
	call write_char
	mov dl,10
	call write_char
	ret
new_line endp

;--- Вывод целого значения ---
;Вход: ax = <значение>
write_int proc
	push si
	mov bx,ax
	or ax,ax
	jns @@1
	neg ax

;выделение цифр и подсчет их количества (в cx)
@@1:
	xor cx,cx
	mov si,10
@@2:
	inc cx
	xor dx,dx
	div si
	add dl,'0'
	push dx
	or ax,ax
	jnz @@2

;добавление знака "-" перед отрицательными значениями
	or bx,bx
	jns @@3
	inc cx
	mov al,'-'
	push ax

;вывод поля
@@3:
	push cx
	neg cx
	add cx,FIELD_WIDTH
	or cx,cx
	jle @@5
@@4:
	push cx
	mov dl,' '
	call write_char
	pop cx
	loop @@4

;вывод числа
@@5:
	pop cx
@@6:	
	pop dx
	call write_char
	loop @@6
	pop si
	ret
write_int endp

;--- Распечатка массива ---
write_array proc
	lea si,a
	mov dx,N
@@1:
	push dx
	mov cx,M
@@2:
	push cx
	lodsw
	call write_int
	pop cx
	loop @@2
	call new_line
	pop dx
	dec dx
	jnz @@1
	ret
write_array endp

msg1	db 'Данный массив:',13,10,'$'
msg2	db 'Номер искомой строки: $'

;массив
a	dw N*M dup(?)

;два последних элемента псевдослучайной последовательности
rnd0	dw ?
rnd	dw ?
	
	end

doctor
to xds
большое спасибо! :thanks:
doctor
to xds
а как быть с первой, если надо ее вызвать через паскаль=) rolleyes.gif
xds
Решение первой задачи на Паскале в виде ассемблерной вставки:
program Sol1;

const
  MaxRows = 100;
  MaxCols = 100;

type
  TArray = array[0..MaxRows - 1, 0..MaxCols - 1] of Integer;

function FindRow(const a: TArray; n, m: Integer): Integer; assembler;
asm
  xor ax,ax
  cmp n,ax       { проверка на случай массива нулевого размера }
  je @@Exit
  cmp m,ax
  je @@Exit
  push ds
  xor di,di      { di = N - <номер искомой строки> }
  mov bx,-MaxInt { bx = <макс. значение суммы> }
  lds si,a
  mov cx,n
@@NextRow:
  push cx
  xor dx,dx      { подсчёт суммы элементов строки }
  mov cx,m
@@NextElem:
  lodsw
  add dx,ax
  loop @@NextElem
  pop cx
  mov ax,MaxCols { переход к следующей строке массива }
  sub ax,n
  shl ax,1
  add si,ax
  cmp dx,bx
  jle @@SkipRow
  xchg bx,dx
  mov di,cx
@@SkipRow:
  loop @@NextRow
  mov ax,di      { <номер искомой строки> = N - di }
  neg ax
  add ax,n
  pop ds
@@Exit:
end

var
  a: TArray;
  n, m, i, j: Integer;

begin
  Write('n>');
  Readln(n);
  Write('m>');
  Readln(m);
  Writeln('Данный массив:');
  Randomize;
  for i := 0 to n - 1 do
    begin
      for j := 0 to m - 1 do
        begin
          a[i, j] := -9 + Random(19);
          Write(a[i, j]:3);
        end;
      Writeln;
    end;
  Writeln;

  Writeln('Номер искомой строки: ', FindRow(a, n, m));
end.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.