Первая серия нулевых элементов - 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
Решение задачи: «Первая серия нулевых элементов»
; ; \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.