8086装配师 [英] 8086 assembly division

查看:126
本文介绍了8086装配师的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个问题与code低于这个数转换成ASCII码数字文本。然而,code似乎在循环的'格'运code

I have this problem with the code below which converts number to ASCII 'number-text'. However the code seems to loop at the 'div' opcode

;Main Program
main:
    mov ax, 0x0000
    mov ds, ax ; setup data segment register
    mov si, GreetString ; setup data segment offset
    call print_string ; call print string procedure
    mov si, DataWord ; setup data segment offset
    mov bl, 0x000A ; base 10
    call format_string ; call format string procedure
    mov si, GreetString ; setup data segment offset
    call print_string ; call print string procedure
prevent_overflow:
    hlt ; halt the CPU
    jmp prevent_overflow

format_string:
mov ax, [ds:si] ; load register ax with data
xor cx, cx ; set counter to 0
mov si, GreetString ; set pointer to address of GreetString

.format_char:
div bl ; divides by register bl
add ah, 48 ; convert to ascii numeric
mov [ds:si], ah ; move ascii numeric to ds:si
inc cx ; increase counter
inc si ; increase si
xor ah, ah ; clear ah register
or ax, ax
jnz .format_char ; jump to format next char
ret

任何想法,为什么会发生这种情况?我说'循环',因为我的CPU是在最高值和DIV后不与运算codeS继续

Any idea why does this happen? I say 'loop' because my CPU is at max-value and does not proceed with the opcodes after div

*更新。谢谢newgre。新增的主要部分,以使其更具可读性(^。^)

*Updated. Thanks newgre. Added main section to make it more readable (^.^)

推荐答案

的问题是,你得到一个分区溢出异常,因为商(在我的例子下面是12345股利10 = 1234 +剩余5)不适合到的8位(记住,已用于其余的?)。

The problem is that you get a division overflow exception because the quotient (in my example below it's 12345 div 10 = 1234 + remainder of 5) doesn't fit into the 8 bits of al (remember that ah is already used by the remainder?).

每一次无论是商或其余不适合目标寄存器,你得到一个部门溢出异常。这不仅是由0分工,导致它。

Every time either the quotient or the remainder doesn't fit into the destination register you get a division overflow exception. It's not only the division by 0 that causes it.

您想要做一个32/16 = 16:16师,而不是16/8 = 8:8师

You want to do a 32/16=16:16 division instead of a 16/8=8:8 division.

下面是在DOS下什么工作与我的变化(记为 ;;;

Here's what works in DOS with my changes (marked as ;;;):

; file: div2.asm
; compile as: nasm -f bin div2.asm -o div2.com
org 0x100 ;;;

;Main Program
main:
    mov ax, 0x0000
;    mov ds, ax ; setup data segment register ;;;
    mov si, GreetString ; setup data segment offset
    call print_string ; call print string procedure
    mov si, DataWord ; setup data segment offset
    mov bl, 0x000A ; base 10
    call format_string ; call format string procedure
    mov si, GreetString ; setup data segment offset
    call print_string ; call print string procedure

    ret ;;;

prevent_overflow:
    hlt ; halt the CPU
    jmp prevent_overflow

format_string:
mov ax, [ds:si] ; load register ax with data
xor cx, cx ; set counter to 0
mov si, GreetString ; set pointer to address of GreetString

.format_char:
; div bl ; divides by register bl ;;;
xor dx, dx ;;;
xor bh, bh ;;;
div bx ;;;

; add ah, 48 ; convert to ascii numeric ;;;
add dl, 48 ;;;

; mov [ds:si], ah ; move ascii numeric to ds:si ;;;
mov [ds:si], dl ; move ascii numeric to ds:si

inc cx ; increase counter
inc si ; increase si
; xor ah, ah ; clear ah register ;;;
or ax, ax
jnz .format_char ; jump to format next char

mov byte [ds:si], "$" ;;;
inc cx ; increase counter ;;;
inc si ; increase si ;;;

ret

print_string: ;;;
    pusha ;;;
    mov ah, 9 ;;;
    mov dx, si ;;;
    int 21h ;;;
    popa ;;;
    ret ;;;

DataWord dw 12345 ;;;
GreetString db "Hello World!", 13, 10, "$" ;;;

它打印:

Hello World!
54321

这篇关于8086装配师的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆