【问题标题】:Min and max from numbers read assembly数字中的最小值和最大值读取程序集
【发布时间】:2022-01-23 05:29:47
【问题描述】:

我刚开始学习汇编,我只是在尝试看看它是如何工作的

下面的代码应该读取 5 个数字并根据使用的助记符 jgjl 显示最小值或最大值

我尝试实现它以读取 5 个数字,然后将最小值 最大值存储在某处,但我不太明白为什么我不能创建像 @987654323 这样的变量@,maxaux 然后将来自ax 寄存器的最后一个值存储在aux 中,并将其与来自ax 的新值进行比较,依此类推

我之所以这样想是因为这是我在C program 中使用的方法

#include <stdio.h>
int main(){
    int min,max,aux;
    scanf("%d%d",&min,&max);
    
    if(min>max){
        aux=min;
        min=max;
        max=min;
    }

    for(int i=0;i<4;i++){

    scanf("%d",&aux);

    if(max<aux) max=aux; 

    if(min>aux) min=aux;

    }
    printf("%d %d",max,min);
}

但我不能像我想的那样分配mov max,ax

我遇到的另一个问题是我无法创建一个函数来调用它进行比较,它只会给出不需要的输出

代码读取 5 个数字然后开始比较它们并将 max/min 值保存在 ax 寄存器中然后打印出来 我使用si 寄存器作为aux 变量,因为我找不到其他解决方案(si 寄存器完全随机选择)

.model small
.stack 100h
.data
msg1 db "Number 1:$"
msg2 db "Number 2:$"
msg3 db "Number 3:$"
msg4 db "Number 4:$"
msg5 db "Number 5:$"
max db "Max :$"
 num1 db ?
 num2 db ?
 num3 db ?
 num4 db ?
 num5 db ?
 ; num6 db ?
.code
mov bl, 00h
mov bh, 9fh
start:
  mov ax, @data
  mov ds, ax
  
  ;nr1
    mov dx, offset msg1
    mov ah, 09h
    int 21h
    
    call readNr
    push dx
    mov num1,al
;nr2
    mov dx, offset msg2
    mov ah, 09h
    int 21h
    
    call readNr
    push dx
    mov num2,al
;nr3    

    mov dx, offset msg3
    mov ah, 09h
    int 21h
    
    call readNr
    push dx
    mov num3,al

  
  ;nr4    

    mov dx, offset msg4
    mov ah, 09h
    int 21h
    
    call readNr
    push dx
    mov num4,al
    
    ;nr5    

    mov dx, offset msg5
    mov ah, 09h
    int 21h
    
    call readNr
    push dx
    mov num5,al
    

;max
    mov dx, offset max
    mov ah, 09h
    int 21h
  
; ;compar:
pop ax
pop dx
mov si,dx
cmp ax,si
  jg exit
  jmp maxim
  
max: 
mov ax,si
;jmp exit

exit: 
mov ax,ax
;loop compar


xor si,si
pop dx
mov si,dx
cmp ax,si
  jg exit1
  jmp maxim1
  
maxim1: 
mov ax,si
;jmp exit

exit1: 
mov ax,ax
;loop compar


xor si,si
pop dx
mov si,dx
cmp ax,si
  jg exit2
  jmp maxim2
  
maxim2: 
mov ax,si
;jmp exit

exit2: 
mov ax,ax

xor si,si
pop dx
mov si,dx
cmp ax,si
  jg exit3
  jmp maxim3
  
maxim3: 
mov ax,si
;jmp exit

exit3: 
mov ax,ax

call displayNr
jmp skipProceduri


readNr proc ;number will be created in dx
    xor bx, bx
    xor dx, dx
    xor cx, cx 
    mov cx, 10
    
    readCf:
        mov ah, 01h
        int 21h
        cmp al, 13
            je finish
        sub al, 48
        mov bl, al
        mov ax, dx
        mul cx
        add ax, bx
        mov dx, ax
        jmp readCf
    
    finish:    
    ret
endp


displayNr proc   
    mov bx, 10
    xor cx, cx
    
    descNr:
        xor dx, dx
        div bx
        inc cx
        push dx
        cmp ax, 0
            je displaynr
        jmp descNr
        
    displaynr:
        pop dx
        add dl, 48
        mov ah, 02h
        int 21h
    loop displaynr

    ret
endp

skipProceduri:

    mov ah, 4ch
    int 21h

end start

【问题讨论】:

  • 这个问题可能已经被问了一百遍了;我只能建议您找出 ABI 中用于 scanf 的哪些寄存器是调用保留的——然后您可以将所有最小/最大值和循环计数器放在那里。

标签: assembly x86-16


【解决方案1】:

您的汇编代码似乎正确!但它确实包含很多冗余指令。

您的解决方案需要一个循环

  pop  ax        ; Consider 5th number as current max
  mov  cx, 4
TheLoop:
  pop  dx        ; 4th, 3rd, 2nd, and 1st number
  cmp  dx, ax
  jng  NotGreater
  mov  ax, dx    ; Set new max
NotGreater: 
  loop TheLoop
  call displayNr

使用基于内存的变量

但我不能像我想的那样分配mov max,ax

当你定义像max db ? 这样的max 变量时,汇编器会抱怨大小不匹配。只需将所有变量定义为单词:

max dw ?
min dw ?
aux dw ?

注意你如何定义你的标签!代码已经有一个 max 标签来表示一些消息 (max db "Max :$")。请参阅下面的 sn-p 我是如何解决这个问题的。

可以从单个循环中获取最大值和最小值。
下一个代码还演示了基于内存的变量的使用,尽管使用寄存器工作会更有效(避免使用慢速 LOOP 指令)!

       mov  cx, 5
TheLoop:
       pop  ax        ; 5th, 4th, 3rd, 2nd, and 1st number
       cmp  ax, max
       jng  NotGreater
       mov  max, ax    ; Set new maximum
NotGreater:
       cmp  ax, min
       jnl  NotLess
       mov  min, ax    ; Set new minimum
NotLess:
       loop TheLoop

       mov  dx, offset msgMax
       mov  ah, 09h
       int  21h
       max  ax, max
       call displayNr

       mov  dx, offset msgMin
       mov  ah, 09h
       int  21h
       max  ax, min
       call displayNr

  ...

max    dw -32768       ; Smallest word integer
min    dw 32767        ; Biggest word integer
msgMax db "Max = $"
msgMin db 13, 10, "Min = $"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-05
    • 2012-10-09
    • 2019-06-24
    • 2014-01-13
    • 1970-01-01
    • 2017-08-01
    • 1970-01-01
    相关资源
    最近更新 更多