英文:
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.
答案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
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论