【问题标题】:TASM checking arguments when cx is modified修改 cx 时 TASM 检查参数
【发布时间】:2014-11-26 00:15:28
【问题描述】:

我需要检查是否给出了大量的参数。目前我的程序知道什么时候没有参数,什么时候给出了两个以上的参数。如果给出了一个,那么它很糟糕,但我的程序无法识别它。我不能做简单的检查,因为当它被允许(当 /? 是参数时)并且 cx 随循环而变化时,有一种可能性。例如,如果我称它为 prog /?,它应该打印描述,当我称它为 prog arg1 arg2 时,它应该被允许,但 prog arg1 不应该。我该如何检查?

  mov ch, 0h         
  mov cl, [es:0080h] 
  push cx
  cmp cx, 0         
  je print_description

  mov bx, 81h          
  jmp search_help

  jmp exit

search_help:
  cmp [es:bx], '?/'  
  je print_description 
  inc bx               
  loop search_help    


  pop cx
  cmp cx, 2
  jne print_description
  mov bx, 82h     
  mov si, offset input_filename 
  mov cx, 255                   

search_input_filename:
  mov dl, [es:bx]               
  inc bx                       
  cmp dl, 20h                  
  je search_output_filename_prep

  mov ds:[si], dl               
  inc si                       
  loop search_input_filename 

search_output_filename_prep:
  mov si, offset output_filename 

search_output_filename:
  mov dl, [es:bx]            
  inc bx                     
  cmp dl, 0Dh             
  je program               
  cmp dl, 20h             
  je print_description     

  mov ds:[si], dl         
  inc si                     
  loop search_output_filename 

【问题讨论】:

  • 这很简单,在你找不到/?之后检查你是否有2个参数。
  • 但 mycx 已更改,我不知道如何比较,推 cx 然后弹出不起作用:(
  • 推送和弹出应该可以工作,就像从内存中重新加载一样(或者甚至只是使用带有内存操作数的cmp)。
  • 但事实并非如此。第二件事呢?你能给我一些样本吗,因为我不知道你在说什么(我在学习 TASM 不是英语)
  • 请注意,80h 处的字节并没有给出参数的数量,而是给出了命令行的长度。这可能就是您的代码不起作用的原因。

标签: assembly x86 command-line-arguments dos tasm


【解决方案1】:

两个错误:

1) 我的 TASM 5.0 不喜欢 [ES:xxxx]。段覆盖必须写为ES:[xxxx]

2) ES:[0080h] 包含命令行的长度,不是参数的数量。因此,这行按照您的想法行事:

push cx
...
pop cx
cmp cx, 2
jne print_description



您可以改用我的get_argc 函数。以下测试用例有效(希望如此):

LOCALS @@
.MODEL small
.STACK 1000h

.DATA
    description db 'description',13,10,'$'
    input_filename db 80 DUP ('$')
    output_filename db 80 DUP ('$')

.CODE
main PROC
        mov ax, @data
        mov ds, ax

        mov ch, 0h
        mov cl, es:[0080h]
        cmp cx, 0
        je print_description

        mov bx, 81h
        jmp search_help

        jmp exit

    search_help:
        cmp word ptr es:[bx], '?/'
        je print_description
        inc bx
        loop search_help

        call get_argc
        cmp ax, 2
        jne print_description

        mov bx, 82h
        mov si, offset input_filename
        mov cx, 255

    search_input_filename:
        mov dl, es:[bx]
        inc bx
        cmp dl, 20h
        je search_output_filename_prep

        mov ds:[si], dl
        inc si
        loop search_input_filename

    search_output_filename_prep:
        mov si, offset output_filename

    search_output_filename:
        mov dl, es:[bx]
        inc bx
        cmp dl, 0Dh
        je program
        cmp dl, 20h
        je print_description

        mov ds:[si], dl
        inc si
        loop search_output_filename

    program:
        mov dx, OFFSET input_filename
        mov ah, 09h
        int 21h
        call crlf
        mov dx, OFFSET output_filename
        mov ah, 09h
        int 21h

    exit:
        mov ax, 4C00h
        int 21h

    print_description:
        lea dx, description
        mov ah, 09h
        int 21h
        mov ax, 4C01h
        int 21h

main ENDP

get_argc PROC
    mov bx, 0
    mov di, 80h
    mov cx, es:[di]

    @@L1:
        inc di
        mov al, es:[di]
        cmp al, 20h
        je @@L1
        cmp al, 09h
        je @@L1
        cmp al, 0Dh
        je @@done

        inc bx

    @@L2:
        inc di
        mov al, es:[di]
        cmp al, 20h
        je @@L1
        cmp al, 09h
        je @@L1
        cmp al, 0Dh
        je @@done
        jmp @@L2

    @@done:
        mov ax, bx
        ret
get_argc ENDP


crlf PROC
        mov ah, 2
        mov dl, 13
        int 21h
        mov ah, 2
        mov dl, 10
        int 21h
        ret
crlf ENDP

END main

【讨论】:

  • 我的 TASM 3.1,这是我大学的要求,不理解 get_argc。
  • @Tomas:TASM 2.01、3.0、3.2、4.0:没问题。尽管如此,我还是稍微更改了代码(删除了.386-directive)。
  • LOCALS @@ 实际上是做什么的?我复制了 call get_argc; cmp斧头,22; jne print_description。编译器说“未定义的符号:get_argc”
  • @Tomas:我发布了一个完整的程序。你可以接受它,编译它并运行它。如果你调用一个过程,你应该有一个过程。在您的文本编辑器中查找符号“get_argc”(所有出现)。提示:程序以PROC 开始,以ENDP 结束。 LOCALS @@ 使所有以 @@ 为前缀的标签都是本地的,即仅从非本地标签(无前缀)知道直到下一个非本地标签。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-26
  • 2011-08-16
  • 2017-10-27
  • 1970-01-01
  • 2020-08-28
相关资源
最近更新 更多