Первая серия нулевых элементов - Assembler

Узнай цену своей работы

Формулировка задачи:

Написал код вроде работает но иногда бывают косяки не могу найти ошибку Условие: Найти первую серию нулевых элементов, заменить элементы этой серии на значения их индексов
data segment
    dwArray dw 32768, 0 ,32768, 0 , 0
    dwDimensionArray dw 5
ends
 
stack segment
    dw   128  dup(0)
ends
 
code segment
start:
; set segment registers:
    mov ax, data
    mov ds, ax
    mov es, ax
    lea si,dwArray 
    mov cx,dwDimensionArray
    sub cx,1
    cycle:
    lodsw
    cmp ax,0
    JNZ end            ; < >
    cmp [si+2],0
    JNZ  end           ; < >
    mov bx,si          ; if =
    end:
    cmp bx,0
    loope cycle
    
    cmp cx,0
    JZ exit 
    sub si,2
    mov bx,1
    cycle2:
    LODSW
    inc bx
    cmp ax,0
    loope cycle2  ;(CX <> 0) and (ZF = 1)
    
    mov cx,bx
    mov ax,bx
    shl bx,1
    sub si,bx
    add si,2
    cycle3: 
    inc ax
    mov [si],ax
    add si,2
    loop cycle3
    
    exit:
    mov ax, 4c00h ; exit to operating system.
    int 21h    
ends
 
end start
с таким массивом не хочет работать а с таким работает 0, 1, 2, 3, 4, 0, 0, 0

Решение задачи: «Первая серия нулевых элементов»

textual
Листинг программы
;
; \MASM\BIN\Ml /c /Cp /nologo /Fl /Sa /Sn Rpl1zIxE.ASM
; \MASM\BIN\Link /MAP /NOLOGO Rpl1zIxE,,;
;
.8086
.DOSSEG
OPTION CASEMAP: NONE
;
CR    EQU   0Dh
LF    EQU   0Ah
;
MaxKBufLen  EQU   80                ; Max.length within CR terminator
MaxArrLen   EQU   MaxKBufLen/2      ; Max.length of array (digit+space->word)
;
KEYB_BUF STRUCT
dbMaxLen    DB    ?
dbCharNum   DB    ?
ChBuf       DB    MaxKBufLen Dup(?)
KEYB_BUF ENDS
;
COMSEG GROUP _CODE, _DATA, _UDATA
;
_DATA SEGMENT Word "Data"
sdAppInfo   DB    "Replaces first sequence of zero words by their indexes"
sdCrLf      DB    CR, LF, "$"
sdEnter     DB    " enter string of separated by spaces words "
            DB    "(empty string - exit)", CR, LF, "$"
sdWrongChar DB    " wrong char.", CR, LF, "$"
sdNoDigit   DB    " no digit", CR, LF, "$"
sdOverflow  DB    " overflow", CR, LF, "$"
sdPointer   DB    "^", CR, LF, "$"
_DATA ENDS
;
_UDATA SEGMENT Word "Data"
dwArray LABEL Word
            DW    MaxArrLen Dup(?)
kbBuf       KEYB_BUF <>
chOutBuf    DB    2*MaxKBufLen Dup(?)
_UDATA ENDS
;
_STACK SEGMENT Stack "Stack"
      DW 128 Dup(?)
_STACK ENDS
;
_CODE SEGMENT Word "Code"
START:
      MOV   DX, COMSEG
      MOV   DS, DX
      MOV   ES, DX
 ASSUME CS:COMSEG, DS:COMSEG, ES:COMSEG
      LEA   DX, sdAppInfo
      CALL  showSd
STR_LOOP:
      CALL  inputArray
      JC    STR_LOOP
      JCXZ  EXIT
      CALL  searchAndRepl
      MOV   SI, DI
      LEA   DI, chOutBuf
      CALL  wordArray2Sd
      MOV   DX, DI
      CALL  showSd
      CALL  crLf
      JMP   STR_LOOP
EXIT:
      MOV   AX, 4C00h
      INT   21h
;
searchAndRepl PROC Uses CX DI
; Input: CX = number of words in array
;        DI = array address
      XOR   AX, AX
      MOV   DX, DI
search0loop:
      REPNE SCASW
      JCXZ  exit
      CMP   [DI], AX
      JNE   search0loop
      SUB   DI, Size dwArray
      INC   CX
      MOV   AX, DI
      SUB   AX, DX
      SHR   AX, 1
      XOR   DX, DX
reploop:
      STOSW
      INC   AX
      CMP   [DI], DX
      JNE   exit
      LOOP  reploop
exit:
      RET
searchAndRepl ENDP
;
inputArray PROC
; Return: CX = number of words in array
;         DI = array address
;         SI = string address
;         if empty string CX = 0
;         if error CF = 1
      LEA   DX, sdEnter
      LEA   SI, kbBuf
      MOV   CL, MaxKBufLen
      CALL  inputSc
      JCXZ  exit
      LEA   DI, dwArray
      CALL  sc2WordArray
      JNC   exit
      MOV   DX, AX
      SUB   CX, Offset [kbBuf].ChBuf
      CALL  showPointer
      CALL  showSd
      STC
exit:
      RET
inputArray ENDP
;
sc2WordArray PROC Uses BX DX DI SI
; Input:  SI = stringCR address
;         DI = array address
; Output: if ok CF = 0
;         CX = array element number
;         if error CF = 1
;         CX = address of error in string
;         AX = address of error message
      XOR   DX, DX            ; Arg count
argloop:
      CALL getArg
      JCXZ  endofargs
str2word:
      CALL  str2Word
      JC    exit
      STOSW
      INC   DX
      JMP   argloop
endofargs:
      MOV   CX, DX
exit:
      RET
sc2WordArray ENDP
;
getArg PROC Uses AX
; Input:  SI = stringCR address
; Output: BX = arg address
;         CX = arg length
;         SI = current position in stringCR
      XOR   CX, CX      ; Arg length
skipspace:
      LODSB
      CMP   AL, CR
      JE    exit
      CMP   AL, " "
      JE    skipspace
      DEC   SI
      MOV   BX, SI
searchargterm:
      LODSB
      CMP   AL, CR
      JE    argfound
      CMP   AL, " "
      JE    argfound
      INC   CX
      JMP   searchargterm
argfound:
      DEC   SI
exit:
      RET
getArg ENDP
;
str2Word PROC Uses BX DX DI SI
; Input:  BX = address of string
;         CX = length of string
; Output: if ok CF = 0
;         AX = word
;         CX = address of string
;         if error CF = 1
;         AX = address of error message
;         CX = address of error in string
      JCXZ  nodig
      XOR   DI, DI      ; Result
      MOV   SI, 1       ; Multiplier
      ADD   BX, CX
convloop:
      CALL  getDecDig
      JC    error
      XOR   AH, AH
      MUL   SI
      JC    overflow
      ADD   DI, AX
      JC    overflow
      MOV   AX, 10
      MUL   SI
      MOV   SI, AX
      JC    skipleadzeros
      LOOP  convloop
      JMP   ok
skipleadzeros:
      DEC   CX
      JZ    ok
      CALL  getDecDig
      JC    error
      TEST  AL, AL
      JZ    skipleadzeros
overflow:
      LEA   AX, sdOverflow
      JMP   error
nodig:
      LEA   AX, sdNoDigit
error:
      STC
      JMP   exit
ok:
      MOV   AX, DI
      CLC
exit:
      MOV   CX, BX
      RET
str2Word ENDP
;
getDecDig PROC
; Input:  BX = next char address
; Output: AL = digit
;         BX = char address
;         if error CF = 1
;         AX = address of error message
      DEC   BX
      MOV   AL, [BX]
      SUB   AL, "0"
      JC    wrongchar
      CMP   AL, 10
      CMC
      JNC   exit
wrongchar:
      LEA   AX, sdWrongChar
exit:
      RET
getDecDig ENDP
;
wordArray2Sd PROC Uses CX DX DI SI
; Input:  SI = Array Address
;         DI = str address
;         CX = Array Length
stloop:
      LODSW
      CALL  word2DecStr
      MOV   AL, " "
      STOSB
      LOOP  stloop
      MOV   AL, "$"
      STOSB
      RET
wordArray2Sd ENDP
;
word2DecStr PROC Uses AX BX CX DX
; Input:  AX = word
;         DI = buffer
; Output: DI = address of next char position
      MOV   BX, 10
      XOR   CX, CX
divloop:
      XOR   DX, DX
      DIV   BX
      PUSH  DX
      INC   CX
      TEST  AX, AX
      JNZ   divloop
stloop:
      POP   AX
      ADD   AL, "0"
      STOSB
      LOOP  stloop
      RET
word2DecStr ENDP
;
inputSc PROC Uses DX
; Input:  DX = message address
;         SI = keyboard buffer address
;         CL = buffer length
; Output: CX = number of chars
;         SI = string address
 ASSUME SI: Ptr KEYB_BUF
      MOV   [SI].dbMaxLen, CL
      CALL  showSd
      MOV   DX, SI
      MOV   AH, 0Ah
      INT   21h
      CALL  crLf
      XOR   CH, CH
      MOV   CL, [SI].dbCharNum      ; String length
      LEA   SI, [SI].ChBuf
 ASSUME SI: Nothing
      RET
inputSc ENDP
;
showPointer PROC Uses DX
; Input: CX = offset of pointer
      MOV   DL, " "
      JCXZ  setptr
sploop:
      CALL  showChar
      LOOP  sploop
setptr:
      LEA   DX, sdPointer
      CALL  showSd
      RET
showPointer ENDP
;
showChar PROC Uses AX
; Input: DL = char
      MOV   AH, 2
      INT   21h
      RET
showChar ENDP
;
crLf PROC Uses DX
      LEA   DX, sdCrLf
      CALL showSd
      RET
crLf ENDP
;
showSd PROC Uses AX
; Input: DS:DX = string address
      MOV   AH, 9
      INT   21h
      RET
showSd ENDP
_CODE ENDS
;
      END   START
;

Объяснение кода листинга программы

The code seems to be written in Assembler and is designed to handle the input of a string of numbers separated by spaces. The main function is searchAndRepl, which is called from START. It is responsible for searching for the maximum number in the input array and replacing it with the index of the first occurrence of the digit. The inputArray function is called to receive the input string. It stores the string in the kbBuf array and sets the CX register to the number of words in the array. The sc2WordArray function is called to convert the string in kbBuf to a word array. It uses the getArg function to get the arguments from the string. The getDecDig function is called by sc2WordArray to convert a single digit to a decimal string. It stores the digit in the AL register and then performs division by 10 to get the number of digits. The word2DecStr function is called by sc2WordArray to convert a word to a decimal string. It uses division by 10 to convert the word to a series of digits, and then stores the digits in the output buffer. The showPointer function is called by searchAndRepl to display the pointer to the character in the array that was replaced. The showChar function is called by showPointer to display a single character. The crLf function is called by searchAndRepl to display a carriage return and line feed. The showSd function is called by crLf to display the string sdCrLf. The start function is the entry point for the program. It initializes the segment registers and calls the searchAndRepl function. Overall, the code seems to be a small utility program that takes a string of numbers as input, finds the maximum number, and replaces it with the index of the first occurrence of the digit.

Оцени полезность:

5   голосов , оценка 4.4 из 5
Похожие ответы