我想编写一个简单的程序来查找数组中最小值。我使用的是英特尔8086架构(如果我对吗?)。问题是我对汇编语言完全不熟悉,我只是无法弄清楚我的代码中出了什么问题,我被卡住了。
最后(退出前)我的ax
注册不包含我的结果
我担心它甚至不会放在那里(我用Turbo Debugger工具检查寄存器和值)。
.MODEL TINY
Data SEGMENT
arr_len EQU 5
arr DB 07h, 02h, 03h, 10h, 12h
minimum DB 255
Data ENDS
Code SEGMENT
ORG 100h
ASSUME CS:Code, DS:Data, SS:Code
Start:
mov ax, SEG Data
mov ds, ax ;load data to ds reg
mov cx, arr_len ;arr_length to counter
mov bx, OFFSET arr ;load first elem.
Search:
inc bx
cmp bl, [minimum] ;compare loaded elem with min
jb Swap ;if bl<minimum
Swap:
mov minimum, bl
loop Search
mov al, minimum ;result here?
mov ax, 4C00h
int 21h
Code ENDS
END Start
有人能告诉我这里有什么问题吗?提前谢谢。
答案 0 :(得分:4)
inc
。这是一个可行的版本:
Search:
mov al, [bx]
cmp al, [minimum] ;compare loaded elem with min
jnb NoSwap ;if al>=minimum
mov [minimum], al ;New minimum
NoSwap:
inc bx
loop Search
答案 1 :(得分:2)
就像Fifoernik的答案所解释的那样,你的条件分支是否会跳到同一个地方,因为分支目标是下一个insn。
如果你积累了minimum
而没有将minimum
留在记忆中,那么该如何做到这一点,因为那太可怕了。
此版本在al
中累积mov
,从不将其存储到内存中。我也使用字符串操作来获得乐趣。您将获得更小的代码大小,但可能比使用si
加载代码更慢。使用loop
作为源指针是一种很好的约定,可以帮助人类跟踪事物,即使不使用字符串操作也是如此。当然,不要让代码变得更糟,但是当你有选择时我会推荐它。
我也避免loop
,因为it's slow and wasn't gaining us much of anything。除非您在代码大小超速的情况下进行硬核优化,否则请不要使用.MODEL TINY
Data SEGMENT
arr DB 07h, 02h, 03h, 10h, 12h
arr_len EQU $-arr ; let the assembler calculate the size to avoid mistakes
Data ENDS
Code SEGMENT
ORG 100h
ASSUME CS:Code, DS:Data, SS:Code
unsigned_min:
;; segment setup not needed with tiny model, according to Fifoernik
; assume arr_len >= 2
mov si, OFFSET arr ; src pointer = &first element
lea di, [si + arr_len] ; end pointer.
;; mov di, arr_len + OFFSET arr ; also works, since input pointer is static
;; or use arr_len + OFFSET arr as an immediate operand for the loop condition, if you don't care about keeping the hard-coded input address out of the loop itself.
cld ; clear the direction flag so string insns count upwards. Omit if the ABI guarantees this state already
lodsb ; al = min so far = first element, and advance si to point to the second element
;; on entry: AL = 1st element (min). SI = pointer to 2nd element. DI = end-pointer
Search:
cmpsb ; compare [si] with current min (al), and ++si
jae .no_new_min
mov al, [si-1] ; conditionally skipped. You could use `cmov` instead of the branch on a CPU supporting 686 insns
.no_new_min
cmp si, di ; loop while si < end
jb Search
; min is in AL
mov ah, 4Ch ; exit with AL as exit status
int 21h
。
arr_len >= 2
如果你不能假设cmp si,di
,那么将min初始化为255或第一个元素,然后输入指向第一个元素而不是第二个元素的循环。或者在循环外使用额外的jb
/ readme.md
。