Wie Sie Anfänger sind, werde ich nur Ihren Code "reparieren", um die falsche Sache richtig zu machen (nicht zu tun, um neuen Code zu schreiben, die richtige Sache überhaupt tun, da das zu viele Änderungen wäre).
.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
(Aber zumindest habe ich einige „Übersicht“, was die Zahlen getan werden müsste in erwarteter Weise anzuzeigen ... wie auch immer, darauf zu achten, zuerst an die kleinen Details, die ich in Ihrem ersten geändert Version)
Alas DOS fehlt eine Funktion für ganze Zahlen Druck, so dass Sie es selbst müssen implementieren, indem einzelne Zeichen zu drucken. Du bist ein Anfänger in Assembler, und das ist fair. Mein Vorschlag ist, dass Sie damit beginnen, diese Funktion in einer Sprache zu implementieren, in der Sie sich wohler fühlen, obwohl Sie nur eine grundlegende 'putchar'-Funktion und keine Bibliotheksunterstützungsfunktionen verwenden. Dies sollte als ausgezeichneter Ausgangspunkt und Referenz für die Umsetzung der Montageäquivalent dienen. – doynax