我需要在二维数组中找到最小数量(程序集)
I need to find minimum number in 2d array (Assembly)
我很不会组装,所以我做了这样的东西。问题是它不起作用。你能帮助我吗?我上网冲浪,看到一些代码可以找到相同元素的数量。我稍微改了一下,但是 move_next
有一些错误。
我的代码:
STACK 256
.data
array dw 1,2,3,4,5,6,7,8,9,0,11,12,13,14,15,16,17,18,19,20
min dw 1
.code
main:
mov ax,@data
mov ds,ax
xor ax,ax
mov si,0
mov bx,0
mov cx,5
external:
mov ax,array[bx][si]
push cx
mov cx,5
mov si,0
iternal:
inc si
cmp ax,min
jle here
loop iternal
here:
jcxz move_next
mov min, ax
move_next <==================== This is your first error
pop cx
add bx,1
loop external
output:
mov ax,min
pop dx
add dl, 30h
int 21h
loop output
mov ah, 09h
int 21h
exit: ;выход
mov ax,4c00h
int 21h
end main
最小值
MODEL small
STACK 256
.data
rows dw 4
cols dw 5
array dw 5,2,3,4,5,6,7,8,9,1,11,12,13,14,15,16,0,18,19,20
min dw 1
newend db 0dh,0ah,'$'
.code
putdigit macro ;макрос виводу чисел массиву
local lput1
local lput2
local exx
push ax
push cx
push -1
mov cx,10
lput1: xor dx,dx
mov ah,0
div cl
mov dl,ah
push dx
cmp al,0
jne lput1
mov ah,2h
lput2: pop dx
cmp dx,-1
je exx
add dl,'0'
int 21h
jmp lput2
exx:
mov dl,' '
int 21h
pop cx
pop ax
endm
main:
mov ax,@data
mov ds,ax
xor ax,ax
mov si,0
mov cx,40
find:
mov ax,array [si]
add si, 2
cmp ax, min
jge not_less
mov min, ax
not_less:
loop find
output:
lea bx,array
mov cx,rows
out1:
mov ah,09h
lea dx,newend
int 21h
push cx
mov cx, cols
mov si, 0
out2:
xor ax, ax
mov ax,[si][bx]
putdigit
add si, 2
loop out2
add bx, cols
pop cx
loop out1
mov ah,09h
lea dx,newend
int 21h
mov ax,min
putdigit
exit:
mov ax,4c00h
int 21h
end main
由于这是作业,所以不会有完整的代码。取而代之的是一些指示。
所以你正在寻找二维数组中的最小值。您找到的示例执行嵌套循环。 严格来说,这是没有必要的,除非你正在寻找最小元素的索引。由于数组在内存中是连续的,您可以在一个循环中扫描整个数组并输出您找到的最小值。在您的情况下,这意味着最初将 CX
初始化为 20,并且没有内部循环。
再来说说扫描数组的逻辑。它类似于 C++ 中的内容 - 获取下一个元素,与 运行 最小值进行比较,如果元素小于最小值,则将元素值分配给最小值。大会为此增添了一些风味。
在 C++ 函数中,您有一个从 0 到(数组大小-1)的索引变量。此处相同,只是您需要考虑数组包含两个字节字(声明为 DW
)这一事实。
回顾一下:
- 初始化寄存器
- 循环 20 次迭代
- 运行 SI 指数
- 加载当前元素到AX
- 将 AX 与 运行 最小值进行比较
- 如果小于,则将 AX 分配给 运行 最小值
- 提高指数
- 继续循环
- 输出并退出
你能做到吗?你不确定哪一部分
关于比较。与 C++ 等高级语言相比,这是汇编中的不同之处之一。 CPU 有一个 FLAGS
寄存器,它根据最后一次算术运算的结果改变它的值。然后,您可以根据各个标志值执行条件跳转。 x86 汇编中没有 if/else
语句 本身 ,只有条件跳转。
具体来说,当你想做 if(ax < min)min=ax
时,在汇编中它会是这样的:
cmp ax, min //Compare ax to min - the FLAGS are set
jge not_less //If ax >= min, jump to the not_less label.
//"ge" stands for "greater or equal"
mov min, ax //Else (that is, if ax < min), assign ax to min
not_less: //This is the label
关于最近的编辑。
首先,您有两次 "output the number" 逻辑 - 一次在 putdigit
中,另一次在您输出最小值的部分。只需为后者重用 putdigit
即可;它打印 AX 的值。将 min
加载到 AX 中并调用 putdigit
.
现在,关于打印数组循环。您的 add bx, cols
线路已关闭;您希望将 BX 的值移动内存中的行大小 ,这不是 5,而是 10,因为您有一个包含两个字节字的数组。另外,即使数字很小并且可以放在一个字节中,加载高字节也是不正确的;而不是 mov al,[si][bx]
,而是 mov ax,[si][bx]
。由于您的汇编器似乎通过数组大小正确缩放 SI,而不是 adc si, 2
恢复 inc si
。 ADC
命令在这里毫无意义。
你有两行 int 21h
行。第一个输出换行符,另一个没有意义。删除它。
代码还有许多其他问题,但让我们先解决这两个问题。
我很不会组装,所以我做了这样的东西。问题是它不起作用。你能帮助我吗?我上网冲浪,看到一些代码可以找到相同元素的数量。我稍微改了一下,但是 move_next
有一些错误。
我的代码:
STACK 256
.data
array dw 1,2,3,4,5,6,7,8,9,0,11,12,13,14,15,16,17,18,19,20
min dw 1
.code
main:
mov ax,@data
mov ds,ax
xor ax,ax
mov si,0
mov bx,0
mov cx,5
external:
mov ax,array[bx][si]
push cx
mov cx,5
mov si,0
iternal:
inc si
cmp ax,min
jle here
loop iternal
here:
jcxz move_next
mov min, ax
move_next <==================== This is your first error
pop cx
add bx,1
loop external
output:
mov ax,min
pop dx
add dl, 30h
int 21h
loop output
mov ah, 09h
int 21h
exit: ;выход
mov ax,4c00h
int 21h
end main
最小值
MODEL small
STACK 256
.data
rows dw 4
cols dw 5
array dw 5,2,3,4,5,6,7,8,9,1,11,12,13,14,15,16,0,18,19,20
min dw 1
newend db 0dh,0ah,'$'
.code
putdigit macro ;макрос виводу чисел массиву
local lput1
local lput2
local exx
push ax
push cx
push -1
mov cx,10
lput1: xor dx,dx
mov ah,0
div cl
mov dl,ah
push dx
cmp al,0
jne lput1
mov ah,2h
lput2: pop dx
cmp dx,-1
je exx
add dl,'0'
int 21h
jmp lput2
exx:
mov dl,' '
int 21h
pop cx
pop ax
endm
main:
mov ax,@data
mov ds,ax
xor ax,ax
mov si,0
mov cx,40
find:
mov ax,array [si]
add si, 2
cmp ax, min
jge not_less
mov min, ax
not_less:
loop find
output:
lea bx,array
mov cx,rows
out1:
mov ah,09h
lea dx,newend
int 21h
push cx
mov cx, cols
mov si, 0
out2:
xor ax, ax
mov ax,[si][bx]
putdigit
add si, 2
loop out2
add bx, cols
pop cx
loop out1
mov ah,09h
lea dx,newend
int 21h
mov ax,min
putdigit
exit:
mov ax,4c00h
int 21h
end main
由于这是作业,所以不会有完整的代码。取而代之的是一些指示。
所以你正在寻找二维数组中的最小值。您找到的示例执行嵌套循环。 严格来说,这是没有必要的,除非你正在寻找最小元素的索引。由于数组在内存中是连续的,您可以在一个循环中扫描整个数组并输出您找到的最小值。在您的情况下,这意味着最初将 CX
初始化为 20,并且没有内部循环。
再来说说扫描数组的逻辑。它类似于 C++ 中的内容 - 获取下一个元素,与 运行 最小值进行比较,如果元素小于最小值,则将元素值分配给最小值。大会为此增添了一些风味。
在 C++ 函数中,您有一个从 0 到(数组大小-1)的索引变量。此处相同,只是您需要考虑数组包含两个字节字(声明为 DW
)这一事实。
回顾一下:
- 初始化寄存器
- 循环 20 次迭代
- 运行 SI 指数
- 加载当前元素到AX
- 将 AX 与 运行 最小值进行比较
- 如果小于,则将 AX 分配给 运行 最小值
- 提高指数
- 继续循环
- 输出并退出
你能做到吗?你不确定哪一部分
关于比较。与 C++ 等高级语言相比,这是汇编中的不同之处之一。 CPU 有一个 FLAGS
寄存器,它根据最后一次算术运算的结果改变它的值。然后,您可以根据各个标志值执行条件跳转。 x86 汇编中没有 if/else
语句 本身 ,只有条件跳转。
具体来说,当你想做 if(ax < min)min=ax
时,在汇编中它会是这样的:
cmp ax, min //Compare ax to min - the FLAGS are set
jge not_less //If ax >= min, jump to the not_less label.
//"ge" stands for "greater or equal"
mov min, ax //Else (that is, if ax < min), assign ax to min
not_less: //This is the label
关于最近的编辑。
首先,您有两次 "output the number" 逻辑 - 一次在 putdigit
中,另一次在您输出最小值的部分。只需为后者重用 putdigit
即可;它打印 AX 的值。将 min
加载到 AX 中并调用 putdigit
.
现在,关于打印数组循环。您的 add bx, cols
线路已关闭;您希望将 BX 的值移动内存中的行大小 ,这不是 5,而是 10,因为您有一个包含两个字节字的数组。另外,即使数字很小并且可以放在一个字节中,加载高字节也是不正确的;而不是 mov al,[si][bx]
,而是 mov ax,[si][bx]
。由于您的汇编器似乎通过数组大小正确缩放 SI,而不是 adc si, 2
恢复 inc si
。 ADC
命令在这里毫无意义。
你有两行 int 21h
行。第一个输出换行符,另一个没有意义。删除它。
代码还有许多其他问题,但让我们先解决这两个问题。