由于您是完全的初学者,我只会“修复”您的代码以正确地执行错误的操作(根本不会费心编写新代码来执行正确的操作,因为无论如何更改都会太多)。
.model small
.stack 100h
; array terminator changed to -128, because signed bytes values can be -128 to +127
; so this new terminator allows for array with values -127 to +127
ARRAY_TERMINATOR EQU -128
; the old '#' is value 35, which makes weird possible range: [-128, +34] U [+36, +127]
.data
elements db 2,-3,-4,5,2,9,ARRAY_TERMINATOR
.code
mov ax, @data
mov ds, ax
mov ax, 03h ; ax = 3 <=> ah = 0 (set mode), al = 3 (text mode)
int 10h ; set default 80x25 text mode (clears screen)
xor si,si ; si = 0 (common x86 assembly idiom how to set zero)
; but it also destroy flags, so in certain cases the "mov r?,0" is needed.
display_loop: ; use meaningful label names, when possible
; using short labels saves time while writing, but wastes time
; while reading + debugging, which you will do lot more often!
; load value first, so you can also compare it from register (faster/shorter)
mov dl, [elements+si] ; it doesn't hurt anything, when dl = -128 at end
; also I would rather put address label inside brackets, the "elements[]"
; way evokes false feeling, that it is array access from C. It is NOT.
; works like that for byte arrays, but already for WORD you need si*2!
; now it's possible to compare for terminator against register dl
cmp dl, ARRAY_TERMINATOR
je exit
add dl, '0' ; you can use ASCII '0' formatting of value 48 to better tell
; source reader, what you are trying to do, which is adding ASCII digit '0'
; try to write source to reflect your human intentions, you can write
; value 48 in many ways: 48, 30h, '0', 32+16, 3*16 ...
; All of them will compile into the same 48, but each tells different story
; to the reader of the source. +48 is arithmetic, +'0' is conversion to ASCII
mov ah, 02h
int 21h
; the code above will display correct digit only for values 0-9
; any other value will be mangled into some other ASCII character
; check ASCII table to get idea what happens for other values (10+48 = ':')
inc si
jmp display_loop ; don't use loop without initializing "cx"
; and don't use "loop" either, do rather "dec cx" "jnz loop"
; "loop" instruction is artifically slowed down to support some legacy code
; Any way, in this case you don't want to loop per cx count, but until
; array terminator is hit, so use "jmp" instead to jump every time
; to fix the output the inner part of loop would have to:
; display char '-' when value is negative (for example for value -123).
; convert absolute value into digit characters in base-10 (decimal) formatting
; which involves dividing the value by 10 until zero and remembering remainders
; For example |-123| = +123 => would produce remainders: 3, 2 and 1
; Then you add '0' to each remainder, and display them in reversed order.
; display ', ' characters (for start even after last number, when works, improve)
; (logic to avoid last comma requires often some thought and more code
; one usual way is to display first number without comma, and rest of array
; starts by displaying comma, then number)
exit:
mov ah, 04ch
int 21h
end
(但至少我添加了一些“概述”,必须做些什么才能以预期的方式显示数字......无论如何,首先要注意我在你的第一个版本中更改的微小细节)