大会8086 |数组的总和,打印多位数字

时间:2016-11-09 09:03:37

标签: assembly x86-16

我在asm x8086中编写了一个非常简单的代码,我正面临一个错误。如果有人能帮我一个简短的解释,我会非常感激。

for fn in files:
    shutil.copy(fn, dirname)

2 个答案:

答案 0 :(得分:3)

如您的评论中所述,add要更正mov替换为EndLoop: mov dl, [sum] mov ah, 02h ;Single character output int 21h ; -------------------------- exit: mov ax, 4c00h int 21h 请注意,行:add al,[bx]实际上是mov al,[bx] )标签 EndLoop 的函数调用只是错误的!

您想要显示总和,并且正在使用DOS打印功能。这个函数09h期望DS:DX中没有你提供的指针!
即使你这样做了,你仍然需要在其文本表示中转换 sum 数字。

这里的快速解决方案是自己满足并只以单个ASCII字符的形式显示结果。硬编码的总和是52,所以它是一个可显示的字符:

mov al,[sum]
mov ah,0
mov dl,10
div dl        ---> AL=5   AH=2
add ax,3030h  ---> AL="5" AH="2"
mov dh,ah     ;preserve AH
mov dl,al
mov ah,02h
int 21h
mov dl,dh     ;restore
int 21h

更进一步,我们可以显示" 52":

Gene1 Gene2   p-value
TP53  ARID1A  0.001
ATM   ATR     0.0005

答案 1 :(得分:1)

我根本没有看到任何错误,代码会对数组求和,显示一些随机的sh * t,然后退出。

您可能想要显示总和的结果?

int 21h, ah=9将在'$'指向的内存中显示dx终止的字符串。

所以你需要两件事,将[sum]中的数字转换为结束时'$'终止的字符串,然后将dx设置为int 21h之前的转换字符串

您可以尝试从此处提取number2string程序:https://stackoverflow.com/a/29826819/4271923

我个人会改变它,将si中目标缓冲区的地址作为另一个调用参数(即从程序体中删除mov si,offset str)。像这样:

PROC number2string
  ; arguments:
  ;  ax = unsigned number to convert
  ;  si = pointer to string buffer (must have 6+ bytes)
  ; modifies: ax, bx, cx, dx, si
    mov  bx, 10  ; radix 10 (decimal number formatting)
    xor  cx, cx  ; counter of extracted digits set to zero
number2string_divide_by_radix:
  ; calculate single digit
    xor  dx, dx  ; dx = 0 (dx:ax = 32b number to divide)
    div  bx      ; divide dx:ax by radix, remainder will be in dx
  ; store the remainder in stack
    push dx
    inc  cx
  ; loop till number is zero
    test ax, ax
    jnz  number2string_divide_by_radix
  ; now convert stored digits in stack into string
number2string_write_string:
    pop  dx
    add  dl, '0' ; convert 0-9 value into '0'-'9' ASCII character encoding
  ; store character at end of string
    mov  [si], dl
    inc  si
  ; loop till all digits are written
    dec  cx
    jnz  number2string_write_string
  ; store '$' terminator at end
    mov  BYTE PTR [si],'$'
    ret
ENDP

然后在你的EndLoop调用它,你需要添加到数据段numberStr DB 8 DUP (0)中,为字符串分配一些内存缓冲区并添加到代码中:

    ; load sum as 16b unsigned value into ax
      xor  ax,ax      ; ax = 0
      mov  al,[sum]   ; ax = sum (16b zero extended)
    ; convert it to string
      mov  si,OFFSET numberStr
      call number2string
    ; display the '$' terminated string
      mov  dx,OFFSET numberStr
      mov  ah,9
      int  21h
    ; ... exit ...