DOSBox上的NASM-程序似乎与另一个程序合并

时间:2018-12-11 20:43:19

标签: assembly nasm dos x86-16 dosbox

我在DOSBox中启动的ASM代码遇到了一个奇怪的问题。我写了以下代码:

      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行之间快速切换。但是,在执行我的代码时,我的程序似乎与其他程序合并,即代码中的命令后面跟随着一些完全与我的代码无关的其他命令。这是示例: https://serverfault.com/questions/796674/block-masking-url-from-nginx/ 我的代码在左侧,反汇编程序输出在右侧。您可以从sub cx, 0Fh中看到以下命令,而其他代码以iret结尾,从而导致无限循环。

我正在使用NASM版本2.12.01,并通过nasm -f bin example.asm -o example.com为DOS汇编可执行文件。我使用DOSBox 0.74版执行汇编程序。

0 个答案:

没有答案