Учебник по ассемблеру (ASM)
 

Ассемблер в примерах - Замена нулевых элементов массива на их порядковые номера

Вопрос:
Дано описание X db 50 dup (?); массив чисел без знака. Написать процедуру на языке ASSEMBLER, заменяющую нулевые элементы массива на их порядковые номера с использованием индексной адресации. Написать вызывающий модуль для процедуры. Процедура и вызывающая программа размещены в разных модулях, используют общую область памяти. (не уверен до или после компеляции, лучше после)

Ответ:
Этот файл я назвал s_main.asm - Это вызывающая программа

text segment 'code'
   assume cs:text, ds:data, es:data, ss:mystack
   EXTRN ChangeElems:near, showArray:near  ; есть такая где-то ВНЕ, ближнего вызова
start:   
     mov ax, data
     mov ds, ax
     
     mov ax, 3
     int 10h
     
     lea si, X
     mov cx, x_len
     CALL ChangeElems
     
     CALL showArray
     
     lea dx, Press_any_key
     mov ah, 9
     int 21h
     
     xor ax, ax
     int 16h
     
     mov ax, 4C00h
     int 21h
     
text ends

data segment 'data' ; сегмент данных
  X     db  1,1,1,0,1,1
  x_len equ $-X
  
  Press_any_Key db 13,10,'Press any key ...$'
data ends

mystack  segment stack 'stack'
 db 100h dup (?)
mystack  ends 

end start ; в главном модуле end с указанием точки входа

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

pseg segment 'code'   ; объявляем сегмент типа 'code'
    assume cs:pseg    ; устанваливаем этот сегмент к качестве сегмента кода
    public ChangeElems, showArray  ; эта процедура может быть вызвана из другого сегмента
    
ChangeElems proc near   ; начало процедуры, указан тип вызова - ближний
; предполагается, что DS:SI указывает на начало массива
; и СХ число элементов в массиве    
  push ax
  push cx
  push si
  push bx
  
    mov bx, 1 ; будет счетчик элементов
@@1:
    mov al, [si+bx-1]  ; но точнее эта адресация называется базово-индексная
    or  al, al ; устанавливает флаги нуля, знака
    jnz @@2    ; переход, если не ноль
      mov [si+bx-1], bl
@@2:    
    inc bl
    LOOP @@1    
  
  pop  bx   
  pop  si
  pop  cx
  pop  ax
  ret
ChangeElems endp  

showArray  proc near
; предполагается, что DS:SI указывает на начало массива
; и СХ число элементов в массиве    
  push ax
  push cx
  push bx
    xor bx, bx
next:
    mov al, [si+bx]
    CALL byte_DEC     
    inc bx
    LOOP next
      mov al, 13 ; два символа для перевода на следующую строку
      int 29h
      mov al, 10
      int 29h      
  pop  bx
  pop  cx
  pop  ax
  ret
showArray endp  

byte_DEC proc ; а эта подпрограмма локальная. Выводит байт в десятичном
; байт должен находиться в AL
  push bx
  push cx
     xor cx, cx
     mov bl, 10
@@show_1:
     xor ah, ah
     div  bl   
     push ax
     inc  cx
     or   al, al
     jnz @@show_1
@@show_2:
     pop  ax
     xchg ah, al
     add  al, '0'
     int  29h     
     LOOP @@show_2
     mov  al, ' ' ; два пробела для отделения одного числа от другого
     int  29h
     int 29h
  pop  cx
  pop  bx 
  ret
byte_DEC endp 

pseg ends             ; конец сегмента
end


   Вперёд
   Содержание