NASM на DOSBox - Программа как бы сливается с другой программой - PullRequest
0 голосов
/ 11 декабря 2018

У меня странная проблема с моим ASM-кодом, запущенным в DOSBox.Я написал следующий код:

      section  .text
      global   start
start:    
      ; Getting command line arguments
      xor      si, si
      xor      ax, ax
      mov      byte [st], 0
      mov      al, [ds:80h]             ; Getting arguments' string length
      mov      si, ax                   ; Storing in index register
      mov      byte [ds:81h+si], 0      ; Adding string termination symbol

      ; Opening file
      mov      dx, 82h                  ; Filename address
      mov      al, 0                    ; Read-only mode
      mov      ah, 3Dh                  ; Calling 3Dh interrupt
      int      21h
      jc       exit
      mov      bx, ax

  ; Calculating number of lines
      mov      cx, 0                    ; Zeroing counter
calclp:   lea      dx, [buf]                ; Getting buffer address
      mov      ah, 3Fh                  ; Calling read
      push     cx                       ; Storing counter
      mov      cx, 40                   ; Reading 40 bytes
      int      21h                      ; Calling interrupt
      cmp      ax, 0                    ; If ax = 0, no symbols were read -> EOF, exiting
      je       findlast
      add      dx, ax                   
      mov      bp, dx
      mov      byte [ds:bp], 0          ; Putting zero at the end of the string
      pop      cx                       ; Restoring cx
      xor      si, si                   ; Zeroing index
      lea      bp, [buf]                ; Getting buffer address
calcchlp: mov      dl, [bp+si]              ; Getting char from buffer
      inc      si
      cmp      dl, 0                    ; If zero - end of buffer
      je       calclp                   ; Reading another 40 bytes
      cmp      dl, 0Ah                  ; If newline - incrementing counter
      jne      calcchlp                 ; If not - continuing loop
      inc      cx
      jmp      calcchlp

findlast: pop      cx
      lea      bp, [ln]                 ; Saving the result
      mov      [bp], cx                 
      lea      bp, [lastb]              ; Zeroing lastb
      mov      word [bp], 0
      mov      word [bp+2], 0
      sub      cx, 0Fh                   
      cmp      cx, 0                    ; If number of lines =< 15, the first and the last 15 lines are the same
      jle      clear                    ; In that case, simply exiting, leaving lastb = 0

      mov      ah, 42h                  ; Resetting file pointer to the start of the file
      mov      al, 0h
      mov      cx, 0
      mov      dx, 0
      int      21h

flcalclp: lea      dx, [buf]                ; Getting buffer address
      mov      ah, 3Fh                  ; Calling read
      push     cx                       ; Storing line counter
      mov      cx, 40                   ; Reading 40 bytes
      int      21h                      ; Calling interrupt
      cmp      ax, 0                    ; If ax = 0, no symbols were read -> EOF, though we should not reach EOF here
      je       exit                     ; In that case, it's error - exiting
      add      dx, ax
      mov      bp, dx
      mov      byte [ds:bp], 0          ; Putting zero at the end of the string
      pop      cx                       ; Restoring cx
      xor      si, si                   ; Zeroing index
      lea      bp, [buf]                ; Getting buffer address
flchlp:   mov      dl, [bp+si]              ; Getting char from buffer
      inc      si
      cmp      dl, 0                    ; If zero - end of buffer
      je       flcalclp                 ; Reading another 40 bytes
      cmp      dl, 0Ah                  ; If newline - decrementing counter
      jne      flchlp                   ; If not - continuing loop
      dec      cx
      cmp      cx, 0                    ; If counter = 0, we reached 15th line from the end
      je       getlastb                 ; Jumping to finding actual byte number
      jmp      flchlp                    

      ; Calling seek to find the exact byte number
getlastb: mov      ah, 42h                  ; Seek call
      mov      al, 1h                   ; Seeking from the current position
      mov      cx, 0                    ; Offset = 0
      mov      dx, 0
      int      21h
      jc       exit
      lea      bp, [lastb]              ; DX:AX contains offset from the start, storing it
      mov      [bp], ax
      mov      [bp+2], dx              

      mov      ah, 42h                  ; Resetting file pointer to the start of the file
      mov      al, 0h
      mov      cx, 0
      mov      dx, 0
      int      21h   

      ; Clearing the screen
clear:    mov      al, 03h                  ; 80x25, 16 colors video mode
      mov      ah, 0h                   ; Enabling video mode
      int      10h

      ; Printing 15 lines
      mov      cx, 15                   ; Line counter for 15 lines 
printlp:  lea      dx, [buf]                ; Getting buffer address
      mov      ah, 3Fh                  ; Read function
      push     cx                       ; Saving cx
      mov      cx, 40                   ; Number of bytes to read
      int      21h                      ; Reading into buffer
      cmp      ax, 0
      je       keyproc
      add      dx, ax
      mov      bp, dx
      mov      byte [ds:bp], 0          ; Putting zero at the end of the string
      pop      cx                       ; Restoring cx
      xor      si, si                   ; Zeroing index
      lea      bp, [buf]                ; Getting buffer address
charlp:   mov      dl, [bp+si]              ; Getting char from buffer
      cmp      dl, 0                    ; Checking if symbol is zero 
      je       printlp                  ; If it is, reading another line
      cmp      dl, 0Ah                  ; Checking if symbol is newline
      jne      printch                  ; If it's not, jumpt to printing it
      dec      cx                       ; Decrementing line counter
      cmp      cx, 0                    ; Checking if counter = 0
      je       keyproc                  ; If it is, we printed all the lines, exit loop
printch:  mov      ah, 02h                  ; Calling stdout write
      int      21h
      inc      si                       ; Incrementing index
      jmp      charlp                   

keyproc:  mov      ah, 0                    ; Waiting for a key to be pressed
      int      16h
      cmp      al, 20h                  ; if space, swap state
      je       swap
      cmp      al, 71h                  ; if q, quit
      jne      keyproc
      mov      ax, 0                    ; exit code 0
      jmp      exit

swap:     cmp      byte [st], 0             ; Checking state variable
      je       toend                    ; If it's 0, jumping to the last 15 lines, otherwise to the first 
tostart:  mov      byte [st], 1             ; Swapping state
      mov      ah, 42h                  ; Calling seek file
      mov      al, 0                    ; From the beginning
      mov      cx, 0                    ; Offset is 0
      mov      dx, 0
      int      21h                      
      jc       exit                     ; If error - exit
      jmp      clear                    ; If not - clearing screen and printing text
toend:    mov      byte [st], 0             ; Swapping state
      mov      ah, 42h          
      mov      al, 0                    ; From the start
      lea      bp, [lastb] 
      mov      cx, [bp+16]              ; Offset was calculated before
      mov      dx, [bp]
      int      21h
      jc       exit
      jmp      clear 

exit:     mov      ah, 4Ch
      int      21h

      section  .bss
buf:      resb     40                       ; Text buffer
st:       resb     1                        ; State variable
ln:       resw     1                        ; Number of lines
lastb:    resd     1                        ; Number of the fist byte of the last 15 lines

По сути, я пытаюсь вычислить количество строк в каком-либо файле, а затем быстро переключаюсь между отображением первых 15 и последних 15 строк указанного файла.Однако при выполнении моего кода моя программа, кажется, сливается с какой-то другой программой, то есть за командами в моем коде следуют некоторые другие команды, совершенно чуждые моему коду.Вот пример: my code on the left, disassembly result to the right Мой код находится слева, а вывод дизассемблера - справа.Вы можете видеть, что из sub cx, 0Fh следующие команды являются чем-то другим, а остальная часть этого кода заканчивается на iret, что приводит к бесконечному циклу.

Я использую NASM версии 2.12.01 и собираю исполняемые файлы для DOS через nasm -f bin example.asm -o example.com.Я использую DOSBox версии 0.74 для выполнения собранных программ.

...