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

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

Problem with number output to DOS console in NASM Assembler

问题

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

  1. section .data
  2. x db 3
  3. y db 5
  4. section .text
  5. global _start
  6. _start:
  7. ; Сравним значения x и y
  8. mov al, [x]
  9. cmp al, [y]
  10. ; Если x <= y, переходим к метке less_than
  11. jle less_than
  12. ; Если x > y, переходим к метке greater_than
  13. jmp greater_than
  14. less_than:
  15. ; Найдем полусумму x и y и заменим меньшее значение на нее
  16. mov bl, [x]
  17. add bl, [y]
  18. shr bl, 1
  19. mov [x], bl
  20. ; Умножим большее значение на 2
  21. mov bl, [y]
  22. shl bl, 1
  23. mov [y], bl
  24. ; Выведем значения x и y
  25. mov ah, 02h ; функция вывода символа на экран
  26. mov dl, [x] ; выводим x
  27. add dl, '0' ; преобразуем为字符
  28. int 21h ; вызов BIOS
  29. mov ah, 02h ; функция вывода символа на экран
  30. mov dl, [y] ; выводим y
  31. add dl, '0' ; преобразуем为字符
  32. int 21h ; вызов BIOS
  33. ; Завершаем программу
  34. mov ah, 4Ch
  35. xor al, al
  36. int 21h
  37. greater_than:
  38. ; Найдем полусумму x и y и заменим меньшее значение на нее
  39. mov bl, [x]
  40. add bl, [y]
  41. shr bl, 1
  42. mov [y], bl
  43. ; Умножим большее значение на 2
  44. mov bl, [x]
  45. shl bl, 1
  46. mov [x], bl
  47. ; Выведем значения x и y
  48. mov ah, 02h ; функция вывода символа на экран
  49. mov dl, [x] ; выводим x
  50. add dl, '0' ; преобразуем为字符
  51. int 21h ; вызов BIOS
  52. mov ah, 02h ; функция вывода символа на экран
  53. mov dl, [y] ; выводим y
  54. add dl, '0' ; преобразуем为字符
  55. int 21h ; вызов BIOS
  56. ; Завершаем программу
  57. mov ah, 4Ch
  58. xor al, al
  59. 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.

  1. section .data
  2. x dw 3
  3. y dw 5
  4. section .text
  5. global _start
  6. _start:
  7. ; Сравним значения x и y
  8. mov ax, [x]
  9. cmp ax, [y]
  10. ; Если x <= y, переходим к метке less_than
  11. jle less_than
  12. ; Если x > y, переходим к метке greater_than
  13. jmp greater_than
  14. less_than:
  15. ; Найдем полусумму x и y и заменим меньшее значение на нее
  16. mov bx, [x]
  17. add bx, [y]
  18. shr bx, 1
  19. mov [x], bx
  20. ; Умножим большее значение на 2
  21. mov bx, [y]
  22. shl bx, 1
  23. mov [y], bx
  24. ; Выведем значения x и y
  25. mov ah, 02h ; функция вывода символа на экран
  26. mov dl, byte [x] ; выводим x
  27. add dl, '0' ; преобразуем в символ
  28. int 21h ; вызов BIOS
  29. mov ah, 02h ; функция вывода символа на экран
  30. mov dl, byte [y] ; выводим y
  31. add dl, '0' ; преобразуем в символ
  32. int 21h ; вызов BIOS
  33. ; Завершаем программу
  34. mov ah, 4Ch
  35. xor al, al
  36. int 21h
  37. greater_than:
  38. ; Найдем полусумму x и y и заменим меньшее значение на нее
  39. mov bx, [x]
  40. add bx, [y]
  41. shr bx, 1
  42. mov [y], bx
  43. ; Умножим большее значение на 2
  44. mov bx, [x]
  45. shl bx, 1
  46. mov [x], bx
  47. ; Выведем значения x и y
  48. mov ah, 02h ; функция вывода символа на экран
  49. mov dl, byte [x] ; выводим x
  50. add dl, '0' ; преобразуем в символ
  51. int 21h ; вызов BIOS
  52. mov ah, 02h ; функция вывода символа на экран
  53. mov dl, byte [y] ; выводим y
  54. add dl, '0' ; преобразуем в символ
  55. int 21h ; вызов BIOS
  56. ; Завершаем программу
  57. mov ah, 4Ch
  58. xor al, al
  59. 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)

  1. mov bx, [x]
  2. add bx, [y]
  3. shr bx, 1 ; -> BX is "half-sum of x and y"
  4. mov ax, [x]
  5. mul word [y]
  6. shl ax, 1 ; -> AX is "twice the multiplication of x and y"

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

  1. mov cx, [x]
  2. cmp cx, [y]
  3. jl less_than
  4. xchg ax, bx ; 仅交换新值
  5. less_than:
  6. mov [x], bx
  7. 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)

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

    1. mov cx, [x]
    2. cmp cx, [y]
    3. jl less_than
    4. xchg ax, bx ; Just swapping the new values
    5. less_than:
    6. mov [x], bx
    7. 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:

确定