在 x86 程序集中将整数打印到控制台
当我在 16 位汇编中添加两个值时,将结果打印到控制台的最佳方法是什么?
目前我有这样的代码:
;;---CODE START---;;
mov ax, 1 ;put 1 into ax
add ax, 2 ; add 2 to ax current value
mov ah,2 ; 2 is the function number of output char in the DOS Services.
mov dl, ax ; DL takes the value.
int 21h ; calls DOS Services
mov ah,4Ch ; 4Ch is the function number for exit program in DOS Services.
int 21h ; function 4Ch doesn't care about anything in the registers.
;;---CODE END---;;
我认为 dl 值应该是 ASCII 代码,但我不确定如何将加法后的 ax 值转换为 ASCII。
When I add two values in 16 bit assembly, what is the best way to print the result to console?
At the moment I have this code:
;;---CODE START---;;
mov ax, 1 ;put 1 into ax
add ax, 2 ; add 2 to ax current value
mov ah,2 ; 2 is the function number of output char in the DOS Services.
mov dl, ax ; DL takes the value.
int 21h ; calls DOS Services
mov ah,4Ch ; 4Ch is the function number for exit program in DOS Services.
int 21h ; function 4Ch doesn't care about anything in the registers.
;;---CODE END---;;
I think that dl value should be in ASCII code, but I'm not sure how to convert ax value after addition into ASCII.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您基本上想要除以 10,打印余数(一位数),然后重复商。
附带说明一下,您的代码中存在一个错误:
您将
2
放入ah
中,然后将ax
放入>dl
。在打印之前,你基本上是在废弃ax
。由于
dl
是 8 位宽,而ax
是 16 位宽,因此您还会遇到大小不匹配的情况。您应该做的是翻转最后两行并修复大小不匹配的问题:
You basically want to divide by 10, print the remainder (one digit), and then repeat with the quotient.
As a side note, you have a bug in your code right here:
You put
2
inah
, and then you putax
indl
. You're basically junkingax
before printing it.You also have a size mismatch since
dl
is 8 bits wide andax
is 16 bits wide.What you should do is flip the last two lines and fix the size mismatch:
只是修复 @Nathan Fellman 代码的顺序
Just fixing the order of @Nathan Fellman 's code
基本算法是:
请注意,这将以相反的顺序生成数字,因此您可能需要用存储每个数字的内容替换“发出”步骤,以便稍后可以对存储的数字进行反向迭代。
另请注意,要将 0 到 9(十进制)之间的二进制数转换为 ascii,只需将“0”的 ascii 代码(即 48)添加到该数字中即可。
The basic algorithm is:
Note that this will yield the digits in the inverse order, so you are probably going to want to replace the "emit" step with something that stores each digit, so that you can later iterate in reverse over the stored digits.
Also, note that to convert a binary number between 0 and 9 (decimal) to ascii, just add the ascii code for '0' (which is 48) to the number.
这不起作用,因为
dl
和ax
具有不同的位大小。您想要做的是创建一个循环,在其中将 16 位值除以 10,记住堆栈上的其余部分,然后使用整数除法结果继续循环。当结果为 0 时,逐位清理堆栈,将这些数字加上 48 将其转换为 ASCII 数字,然后打印它们。This won't work as
dl
andax
have different bit sizes. What you want to do is create a loop in which you divide the 16 bit value by 10, remember the rest on the stack, and then continue the loop with the integer division result. When you reach a result of 0, clean up the stack digit by digit, adding 48 to the digits to turn them into ASCII digits, then print them.接受的答案是错误的,因为它显示的结果相反!这就是我今天写这个答案的原因。我的回答展示了一口气输出结果的更好技术(通过 DOS.function 09h)。
你的代码
始终在
int 21h
指令之前的指令中加载 DOS 函数编号。请务必检查您的大小:您无法从 16 位寄存器移动到 8 位寄存器。
您的号码允许使用 DOS.PrintCharacter 函数。要将值3转换为字符“3”,只需添加48即可在DL中获得ASCII码。
一位数结果的示例
多位结果的解决方案
NASM 使用
mov bx, Buffer + 5
MASM 使用
mov bx, OFFSET Buffer + 5
The accepted answer is wrong in that it displays the result reversed! That's why I write this answer today. My answer demonstrates the better technique of outputting the result in one gulp (via DOS.function 09h).
Your code
Always load the DOS function number in the instruction right before the
int 21h
instruction.Always check your sizes: you cannot move from a 16-bit register to an 8-bit register.
Your numbers allow the use of the DOS.PrintCharacter function. To convert the value 3 into the character "3", you just need to add 48 so as to have an ASCII code in DL.
Your example for a single-digit result
Solution for a multi-digit result
NASM use
mov bx, Buffer + 5
MASM use
mov bx, OFFSET Buffer + 5