【问题标题】:Assembly home-work组装作业
【发布时间】:2017-11-25 17:41:40
【问题描述】:

程序是作业的一部分,问题是 - 程序卡住(冻结)。

通过使用Turbo Debugger,我知道该程序可以运行,并返回correct value (0)。但是,不知道为什么,屏幕上不显示输出,程序卡住了。

程序

 .MODEL SMALL
    .STACK 100h
    .DATA
ANSWER_OUTPUT DB 'The last digit is : x',13,10,'$'
ARR1 DB 1 DUP(123,2,65)
ARR2 DB 1 DUP(1,15,54)
ARR3 DW 3 DUP(0)
MIN_NUMBER DW 0
TEN DW 10
HELP DW 0
TWO DB 2
.CODE
.386
START: 
     MOV AX,@DATA                   ; DS can be written to only through a register
     MOV DS,AX                      ; Set DS to point to data segment
     MOV DI,0
     MOV SI,2
GET_ARR3:
     MOV AL,ARR1[SI]
     CMP AL,ARR2[DI]
     JAE BIGGER
     JMP SMALLER
BIGGER:
     MOV AX,0
     MOV AL,ARR2[DI]
     MOV HELP,AX
     MOV AX,0
     MOV AL,ARR1[SI]
     DIV HELP
     MOV CX,DX
     MOV AX,DI
     MUL TWO
     MOV DI,AX
     MOV ARR3[DI],CX
     DIV TWO
     MOV DI,AX
     INC DI
     SUB SI,1
     CMP DI,3
     JNE GET_ARR3
     JMP FIND_MIN
SMALLER:
     MOV AX,0
     MOV AL,ARR2[DI]
     MOV HELP,AX
     MOV AX,0
     MOV AL,ARR1[SI]
     MUL HELP
     MOV CX,AX
     MOV AX,DI
     MUL TWO
     MOV DI,AX
     MOV ARR3[DI],CX
     DIV TWO
     MOV DI,AX
     INC DI
     SUB SI,1
     CMP DI,3
     JNE GET_ARR3
     MOV AX,0
     MOV AX,ARR3[0]
     MOV MIN_NUMBER,AX
FIND_MIN:
     MOV AX,0
     MOV AX,ARR3[1]
     CMP AX,MIN_NUMBER
     JB CASE_1
     JMP CASE_11
CASE_1:
     MOV MIN_NUMBER,AX
CASE_11:
     MOV AX,0
     MOV AX,ARR3[2]
     CMP AX,MIN_NUMBER
     JB CASE_2
     JMP FIND_DIGIT
CASE_2:
     MOV MIN_NUMBER,AX           
FIND_DIGIT: 
     MOV AX,0
     MOV AX,MIN_NUMBER
     CMP AX,TEN
     JB End_Asm
     DIV TEN
     MOV AL,AH
     MOV AH,0
     MOV MIN_NUMBER,AX
     MOV AX,0
     JMP FIND_DIGIT
End_Asm:
     MOV AX,MIN_NUMBER
     ADD AL,'0'
     MOV ANSWER_OUTPUT[20],AL
     MOV DX,OFFSET ANSWER_OUTPUT    ; Set  DS:DX to point to question_output         
     MOV AH,9                       ; Set print option for int 21h
     INT 21h                        ; Print question_output
     MOV AH,4Ch                     ; Set terminate option for int 21h
     INT 21h                        ; Return to DOS (terminate program)
END START

【问题讨论】:

  • 在调试器中运行时,卡在哪里了?
  • 另外,注释您的代码,特别是如果您希望其他人提供帮助。此外,仔细检查您的操作数大小,您无处不在。更不用说每次你MULDIV 两个,一只小猫死了。
  • 它没有。它在 TurboDebugger 中完美运行。
  • hhhh tnx。这是我第一次来这里,只是第一次学习ASM.. DIV 或 MUL 有什么问题?这么糟糕?
  • mul/div 做 *2 /2 就像纸上的人会通过计算完全乘法并对结果求和来做 2345*10,而不是在 2345 的末尾加零。二进制值“*10”是*2,“/10”是/2,所以你只需在末尾添加/删除一位。这就是左移/右移对二进制值的作用。 ...div HELP 是我看到的第一个错误(您没有将dx 设置为任何东西,但div r/m16 确实将dx:ax 除以r/m16,检查x86.renejeschke.de/html/file_module_x86_id_72.html)...也许TD 更宽容用 dx=0 开始你的代码,而 DOS 不是。

标签: assembly x86-16 tasm


【解决方案1】:

因为您将 HELP 定义为一个单词 (HELP DW 0),所以指令 DIV HELP 会将 DX:AX 除以 HELP。因此你需要将DX归零:

xor dx, dx
DIV HELP

因为您将 TEN 定义为一个单词 (TEN DW 10),所以指令 DIV TEN 会将 DX:AX 除以 TEN。因此你需要将DX归零:

xor dx, dx     <-- You need to change the code (remainder is in DX)
DIV TEN

但是在这种情况下,您只需将 TEN 的定义更改为一个字节并保留现有代码。无论如何,这就是现有代码所期望的!

TEN db 10       <-- You can keep existing code (remainder is in AH)

因为您将 ARR3 数组定义为单词 (ARR3 DW 3 DUP(0)),您可以使用 0、2 和 4 等偏移量来寻址其元素。
你的程序错误地使用了

  • MOV AX,ARR3[1] 其中mov ax, ARR3[2] 是正确的
  • MOV AX,ARR3[2] 其中mov ax, ARR3[4] 是正确的

看了上面的错误,我很难相信“它在 TurboDebugger 中完美运行”。
您可能纯粹是偶然获得了“正确的值 (0)”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-07
    • 1970-01-01
    • 2016-06-06
    • 1970-01-01
    • 1970-01-01
    • 2021-07-26
    • 2016-06-25
    相关资源
    最近更新 更多