问题与在NASM汇编中将数字输出到DOS控制台有关。

huangapple go评论92阅读模式
英文:

Problem with number output to DOS console in NASM Assembler

问题

程序中的问题在于将x和y的默认值设置为了错误的数据类型。在这段汇编代码中,x和y被声明为"dw",这表示它们是字(16位整数),而不是字节。由于x和y的默认值应该是3和5,它们被声明为字,这会导致程序出现错误。应将它们声明为字节("db")以存储正确的默认值。修正后的代码如下:

section .data
x db 3
y db 5

section .text
global _start

_start:
  ; Сравним значения x и y
  mov al, [x]
  cmp al, [y]
  
  ; Если x <= y, переходим к метке less_than
  jle less_than
  
  ; Если x > y, переходим к метке greater_than
  jmp greater_than

less_than:
  ; Найдем полусумму x и y и заменим меньшее значение на нее
  mov bl, [x]
  add bl, [y]
  shr bl, 1
  mov [x], bl
  
  ; Умножим большее значение на 2
  mov bl, [y]
  shl bl, 1
  mov [y], bl
  
  ; Выведем значения x и y
  mov ah, 02h ; функция вывода символа на экран
  mov dl, [x] ; выводим x
  add dl, '0' ; преобразуем为字符
  int 21h ; вызов BIOS
  
  mov ah, 02h ; функция вывода символа на экран
  mov dl, [y] ; выводим y
  add dl, '0' ; преобразуем为字符
  int 21h ; вызов BIOS
  
  ; Завершаем программу
  mov ah, 4Ch
  xor al, al
  int 21h
  
greater_than:
  ; Найдем полусумму x и y и заменим меньшее значение на нее
  mov bl, [x]
  add bl, [y]
  shr bl, 1
  mov [y], bl
  
  ; Умножим большее значение на 2
  mov bl, [x]
  shl bl, 1
  mov [x], bl
  
  ; Выведем значения x и y
  mov ah, 02h ; функция вывода символа на экран
  mov dl, [x] ; выводим x
  add dl, '0' ; преобразуем为字符
  int 21h ; вызов BIOS
  
  mov ah, 02h ; функция вывода символа на экран
  mov dl, [y] ; выводим y
  add dl, '0' ; преобразуем为字符
  int 21h ; вызов BIOS
  
  ; Завершаем программу
  mov ah, 4Ch
  xor al, al
  int 21h

通过将x和y声明为字节并在程序中使用正确的数据类型,程序应该能够正确运行,得到4和30。

英文:

We have the following task: write a program that sets the default values of x and y (in the program these are 3 and 5 respectively), then it compares these numbers and replaces the lesser of them with the half-sum of x and y, and replaces the greater of them with twice the multiplication of x and y.

section .data
x dw 3
y dw 5

section .text
global _start

_start:
  ; Сравним значения x и y
  mov ax, [x]
  cmp ax, [y]
  
  ; Если x <= y, переходим к метке less_than
  jle less_than
  
  ; Если x > y, переходим к метке greater_than
  jmp greater_than

less_than:
  ; Найдем полусумму x и y и заменим меньшее значение на нее
  mov bx, [x]
  add bx, [y]
  shr bx, 1
  mov [x], bx
  
  ; Умножим большее значение на 2
  mov bx, [y]
  shl bx, 1
  mov [y], bx
  
  ; Выведем значения x и y
  mov ah, 02h ; функция вывода символа на экран
  mov dl, byte [x] ; выводим x
  add dl, '0' ; преобразуем в символ
  int 21h ; вызов BIOS
  
  mov ah, 02h ; функция вывода символа на экран
  mov dl, byte [y] ; выводим y
  add dl, '0' ; преобразуем в символ
  int 21h ; вызов BIOS
  
  ; Завершаем программу
  mov ah, 4Ch
  xor al, al
  int 21h
  
greater_than:
  ; Найдем полусумму x и y и заменим меньшее значение на нее
  mov bx, [x]
  add bx, [y]
  shr bx, 1
  mov [y], bx
  
  ; Умножим большее значение на 2
  mov bx, [x]
  shl bx, 1
  mov [x], bx
  
  ; Выведем значения x и y
  mov ah, 02h ; функция вывода символа на экран
  mov dl, byte [x] ; выводим x
  add dl, '0' ; преобразуем в символ
  int 21h ; вызов BIOS
  
  mov ah, 02h ; функция вывода символа на экран
  mov dl, byte [y] ; выводим y
  add dl, '0' ; преобразуем в символ
  int 21h ; вызов BIOS
  
  ; Завершаем программу
  mov ah, 4Ch
  xor al, al
  int 21h

When I compile my program, I get just "Pp" when I should get 4 and 30 respectively.
问题与在NASM汇编中将数字输出到DOS控制台有关。

答案1

得分: 1

其中一个结果(4和30)有多于1位的数字。您需要更好的方法来输出多位数字。请参阅https://stackoverflow.com/questions/45904075/displaying-numbers-with-dos。

然后它比较这些数字,并用x和y的半和替换其中较小的数字,并用x和y的乘积的两倍替换其中较大的数字。

最好的方法是不要首先比较数字,然后不得不重复大量的代码。首先计算替代表达式并将结果保存在寄存器中。 (例如,mov [x],bx将在您下次使用它之前破坏x)

mov bx, [x]
add bx, [y]
shr bx, 1      ; -> BX is "half-sum of x and y"

mov ax, [x]
mul word [y]
shl ax, 1      ; -> AX is "twice the multiplication of x and y"

然后比较数字并相应加载x和y:

mov  cx, [x]
cmp  cx, [y]
jl   less_than
xchg ax, bx    ; 仅交换新值
less_than:
mov  [x], bx
mov  [y], ax

替换其中较小的数字。

jle less_than 指令在LessOrEqual上分支。根据任务描述,它应该变成 jl less_than

英文:

One of your results (4 and 30) has more than 1 digit. You need a better way of outputting the multi-digit numbers. See https://stackoverflow.com/questions/45904075/displaying-numbers-with-dos.


> then it compares these numbers and replaces the lesser of them with the half-sum of x and y, and replaces the greater of them with twice the multiplication of x and y

  • It would be best to not start by comparing the numbers and then have to duplicate a lot of code. First calculate the replacement expressions and keep the results in registers. (eg. mov [x], bx would destroy x before you could use it next)

      mov bx, [x]
      add bx, [y]
      shr bx, 1      ; -> BX is "half-sum of x and y"
    
      mov ax, [x]
      mul word [y]
      shl ax, 1      ; -> AX is "twice the multiplication of x and y"
    
  • Then compare the numbers and load x and y accordingly:

        mov  cx, [x]
        cmp  cx, [y]
        jl   less_than
        xchg ax, bx    ; Just swapping the new values
      less_than:
        mov  [x], bx
        mov  [y], ax
    

> replaces the lesser of them

The jle less_than instruction is branching on LessOrEqual. Following the task description that really should become jl less_than.

huangapple
  • 本文由 发表于 2023年3月12日 19:22:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/75712760.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定