实验10.2

Tutorial: 汇编基础 Category: C语言 Published: 2026-04-07 13:58:26 Views: 20 Likes: 0 Comments: 0
1. 解决除法溢出的问题
  1. 被除数是 16 位, 除数是 8 位。在这种情况下, 被除数放在 ax 中, 除数放在 8 位 reg 或者内存单元中。产生的结果:商放在 al 中, 余数放在 ah 中
  2. 被除数是 32 位, 除数是 16 位。在这种情况下, 被除数的高 16 位放在 dx 中, 低 16 位放在 ax 中, 除数放在 16 位 reg 或者内存单元中。产生的结果:商放在 ax 中, 余数放在 dx 中。

功能:进行不会产生溢出的除法运算, 被除数为 dword 型, 除数为 word 型, 结果为 dword 型。 参数: (ax)=dword 型数据的低 16 位 (dx)=dword 型数据的高 16 位 (cx)=除数 返回: (dx)=结果的高 16 位 (ax)=结果的低 16 位 (cx)=余数

2. 溢出的情况
assume cs:code,ds:data,ss:stack

data segment
           dd 1234567      ; 除以100, 余数67, 16进制43
data ends

stack segment stack
            db 128 dup(0)
stack ends

code segment
      start:
            mov ax, stack
            mov ss,ax
            mov sp,128

            mov bx,data
            mov ds,bx

            mov ax, ds:[0]
            mov dx, ds:[2]
      ; mov bx,100          ; 不溢出的情况 1234567 / 100 = 12345(3039H), 余数67(43H)
      ; AX=D687  BX=0064  CX=00AE  DX=0012  SP=0080  BP=0000  SI=0000  DI=0000
      ; DS=0E24  ES=0E14  SS=0E25  CS=0E2D  IP=0017   NV UP EI PL NZ NA PO NC
      ; 0E2D:0017 F7F3          DIV     BX
      ; -t
      ; AX=3039  BX=0064  CX=00AE  DX=0043  SP=0080  BP=0000  SI=0000  DI=0000
      ; DS=0E24  ES=0E14  SS=0E25  CS=0E2D  IP=0019   NV UP EI PL NZ NA PO NC

            mov bx,10           ; 溢出的情况 1234567 / 10
      ; AX=D687  BX=000A  CX=00AE  DX=0012  SP=0080  BP=0000  SI=0000  DI=0000
      ; DS=0E24  ES=0E14  SS=0E25  CS=0E2D  IP=0017   NV UP EI PL NZ NA PO NC
      ; 0E2D:0017 F7F3          DIV     BX
      ; -t
      ; AX=D687  BX=000A  CX=00AE  DX=0012  SP=007A  BP=0000  SI=0000  DI=0000
      ; DS=0E24  ES=0E14  SS=0E25  CS=F000  IP=CA60   NV UP DI PL NZ NA PO NC

            div bx

            mov ax,4c00h
            int 21h


code ends
end start
3. 实验 10.2
assume cs:code,ds:data,ss:stack
; 32bit div  =>  ax = low 16 bit,  dx = high 16bit
; ax 保存结果, dx 保存余数


; 思路:伪代码, 比如 35

; 3是高位, 给dx
; 5是低位, 给ax

; 3/2=1...1,  商1, push保存起来, 余数1给dx
; ax:dx 重新组成一个数, ax:dx / 2
; dx = 新余数, 给cx
; ax = 新的商
; dx = pop 保存的商1

; 此时:
; ax = 新的商
; dx = 旧的商
; cx = 新余数


data segment
           dd 1234567      ; 除以100, 余数67, 16进制43
data ends

stack segment stack
            db 128 dup(0)
stack ends

code segment
      start:
                 mov  ax, stack
                 mov  ss,ax
                 mov  sp,128

                 mov  bx,data
                 mov  ds,bx
                 call div_number
                 mov  ax,4c00h
                 int  21h

      ;===========================
      long_div:
                 mov  ax, dx
                 mov  dx,0
                 div  cx              ; dx = 余数
                 push ax              ; 保存第一次除的结果
                 mov  ax,ss:[bp]      ; 取出保存的低16bit
                 div  cx              ; dx:ax / cx, dx:余数, ax:低16位, 重新组合一个数除cx
      ; AX=D687  BX=0E24  CX=000A  DX=0008  SP=0078  BP=007C  SI=0000  DI=0000
      ; DS=0E24  ES=0E14  SS=0E25  CS=0E2D  IP=0020   NV UP EI PL NZ NA PE NC
      ; 0E2D:0020 F7F1          DIV     CX
      ; -t
      ; AX=E240  BX=0E24  CX=000A  DX=0007  SP=0078  BP=007C  SI=0000  DI=0000
      ; DS=0E24  ES=0E14  SS=0E25  CS=0E2D  IP=0022   NV UP EI PL NZ NA PE NC
      ; 0E2D:0022 8BCA          MOV     CX,DX
                 mov  cx, dx          ; dx = 余数, 给 cx
                 pop  dx              ; 取出商给dx
      ; AX=E240  BX=0E24  CX=0007  DX=0007  SP=0078  BP=007C  SI=0000  DI=0000
      ; DS=0E24  ES=0E14  SS=0E25  CS=0E2D  IP=0024   NV UP EI PL NZ NA PE NC
      ; 0E2D:0024 5A            POP     DX
      ; -t
      ; AX=E240  BX=0E24  CX=0007  DX=0001  SP=007A  BP=007C  SI=0000  DI=0000
      ; DS=0E24  ES=0E14  SS=0E25  CS=0E2D  IP=0025   NV UP EI PL NZ NA PE NC
      ; 0E2D:      0025 C3            RET

      ; (dx)= 结果的高 16 位 = 0001
      ; (ax)= 结果的低 16 位 = E240
      ; (cx)= 余数
      ; 1E240H = 123456(10) = 1234567/10...7,  cx = 7, 满足题目要求
                 ret
      ;===========================
      div_number:
                 mov  ax, ds:[0]
                 mov  dx, ds:[2]
                 mov  cx, 10          ; 除数, 1234567 / 10
                 push ax              ; 低16bit
                 mov  bp,sp           ; ss:[bp] = AX = 低16bit
                 call long_div
                 add  sp,2            ; call 的时候,push了
                 ret

code ends
end start
Prev: 实验10.1 Next: 实验10.3