[英]Finding the minimum in an array (Intel8086)
I'd like to write a simple program to find the minimum value in an array . 我想编写一个简单的程序来查找数组中的最小值 。 I'm using Intel 8086 architecture (if I'm right?).
我使用的是Intel 8086架构(如果我是对的?)。 The problem is that I am totally new to Assembly language and well, I just cannot figure out what am I doing wrong in my code, I'm stuck.
问题是我对汇编语言完全陌生,好吧,我只是无法弄清楚我在代码中做错了什么,被卡住了。
At the end (before exiting) my ax
register does not contain my result. 最后(退出之前),我的
ax
寄存器不包含我的结果。
I'm afraid it doesn't even place it there (I check registers' values with Turbo Debugger tool). 恐怕它甚至都不会放在那儿(我用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
Could anyone give me advices what is wrong here? 谁能给我建议这里出了什么问题? Thanks in advance.
提前致谢。
inc
before looping only. inc
。 Here's a version that can work: 这是可以使用的版本:
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
Like Fifoernik's answer explained, your conditional branch jumps to the same place whether it's taken or not, because the branch target is the next insn. 就像Fifoernik的答案所解释的那样,无论是否采用条件分支,您的条件分支都会跳转到同一位置,因为分支目标是下一个insn。
Here's how to do it without keeping your minimum
in memory as you accumulate it, because that's horrible. 这是在不累积
minimum
内存的情况下执行此操作的方法,因为这太可怕了。
This version accumulates minimum
in al
, never storing it to memory. 此版本累积的
minimum
为al
,永远不会将其存储到内存中。 I also used string ops for fun. 我还使用了字符串操作来娱乐。 You'll get smaller code size, but maybe slower code than loading with
mov
. 您将获得较小的代码大小,但与使用
mov
加载相比,代码可能会更慢。 Using si
as a source pointer is a good convention to help humans keep track of things, even when not using string ops. 使用
si
作为源指针是一个很好的约定,即使没有使用字符串操作,也可以帮助人们跟踪事物。 Don't make the code worse just for that, of course, but I recommend it when you have the choice. 当然,不要为此而使代码变糟,但是我建议您在有选择的情况下使用它。
I also avoid loop
because it's slow and wasn't gaining us much of anything . 我还避免
loop
因为它很慢并且没有为我们带来任何好处 。 Unless you're going hard-core optimizing for code-size over speed, don't use loop
. 除非您要对速度进行代码大小的硬性优化,否则请不要使用
loop
。
.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
If you can't assume arr_len >= 2
, then initialize min to 255 or the first element, and enter the loop with it pointing to the first element, instead of 2nd. 如果不能假定
arr_len >= 2
,则将min初始化为255或第一个元素,然后输入指向第一个元素而不是2nd的循环。 Or use an extra cmp si,di
/ jb
outside the loop. 或在循环外使用额外的
cmp si,di
/ jb
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.