问题描述
我在Windows 7 HP x64,Intel i3-2330m PC上使用EMU8086.
I'm using EMU8086 on a Windows 7 HP x64, Intel i3-2330m PC.
我花了大约两个星期的时间研究和修改此汇编语言程序,以打印用户输入的整数的十六进制值.我从直接从存储位置打印值一无所获.如有必要,我可以编写代码以将字符串转换为十六进制.但是,我试图避免多余的代码行来执行此操作. (我认为这就是优化.)
I have spent about two weeks researching and tinkering with this Assembly language program in an effort to print the hex value of an integer entered by the user. I have found nothing about directly printing a value from a memory location. I can, if necessary, write the code to do the string conversion to hex. However, I am attempting to avoid the extra lines of code to do this. (I think that is called optimizing.)
我的研究使我对Corbin在此站点上发表的评论上面写着:
My research has lead me to a comment on this site by Corbin which says:
这些都没有把我引向我要执行任务的方式.
None of this has directed me to a manner in which I desire to perform the task.
我已经逐步编写并测试了代码,并收到了预期的结果.通过查看变量并查看CX寄存器,我可以确认它们的值就是我要打印的值.
I have written and tested the code incrementally, receiving the desired results. By watching the variable and viewing the CX register, I can confirm that their values are the values I want to print.
我在这里包括我的代码.它可能很难看,而且肯定被过分评论.发表评论对我有好处,可以帮助我学习/记住自己在进步中所做的事情.
I am including my code here. It is probably ugly and is definitely over-commented. The commenting is for my benefit to help me learn/remember what I have done as I progress.
; program name: convert_decimal_to_hex
; by W K
; August, 2015
; This program accepts an integer between 1 and 10000 and
; prints the hexadecimal value to the console
;
;
#MAKE_COM# ;instruct compiler to make COM file
include emu8086.inc ;use include file for macros
ORG 100h ;directive for COM program, set offset to 100h
;
MOV DX, offset msg1 ;moves value of msg1 to the data register
;
MOV AH, 9 ;moves the value 9 to the high accumulator register
;to be used with the interrupt
INT 21h ;invokes interrupt to print string to DOS window
;
MOV DX,13 ;these lines
MOV AH,2 ;create a
INT 21h ;newline
MOV DX,10 ;and
MOV AH,2 ;move the cursor
INT 21h ;to the newline
;
CALL SCAN_NUM ;calls macro to scan numeric keyboard input
;error catching is included in macro
;number is stored in CX
MOV DX,13 ;these lines
MOV AH,2 ;create a
INT 21h ;newline
MOV DX,10 ;and
MOV AH,2 ;move the cursor
INT 21h ;to the newline
;
MOV DX, offset msg2 ;moves value of msg2 to the data register
MOV AX, CX ;copies scanned number to AX to be printed
;as part of message
;MOV AH, 9 ;moves the value 9 to the high accumulator register
;to be used with the interrupt
;INT 21h ;invokes interrupt to print string to DOS window
CALL PRINT_NUM_UNS ;prints hexadecimal value at end of msg2
MOV CONVERTEDNUMBER, CX
;
MOV AH, 9 ;moves the value 9 to the high accumulator register
;to be used with the interrupt
INT 21h ;invokes interrupt to print string to DOS window
;
MOV AX, 0 ;wait for any key
INT 16h ;prevents window from closing immediately
;
msg1 db "Type an integer between 1 and 10000, and press enter. $"
;declare string variable
msg2 db " in hexadecimal is: $"
;
DEFINE_SCAN_NUM ;defines macro from include file
;gets multidigit signed number from keyboard
DEFINE_PRINT_NUM_UNS ;defines macro from include file
;prints unsigned number in AX
;
CONVERTEDNUMBER DW 0 ;declare variable
;
RET ;return to operating system
END ;directive to stop compiler
是否有一个过程可以直接打印变量值或CX寄存器值,而无需编写代码行来转换用户输入的字符串值?对文章,代码示例或其他有用建议的任何引用将不胜感激.
Is there a procedure to directly print the variable value or CX register value without writing the lines of code to convert the string value input by the user? Any references to articles, code examples, or other helpful advice will be greatly appreciated.
推荐答案
DOS仅向您提供将字符写入标准输出的中断(对于单个字符,INT 21H / AH=2
,而INT 21H / AH=9
以$
终止的字符串).
DOS only provides you with interrupts to write characters to the standard output (INT 21H / AH=2
for a single character, and INT 21H / AH=9
for a $
-terminated string of characters).
因此,您将必须首先将任何要打印的数字转换为字符串,无论您希望以何种形式显示该数字.幸运的是,这很容易做到.下面是一个示例如何显示32位十六进制数字的示例(我将作为练习来剥离前导零):
So you will have to convert any number you want to print into a string first, in whatever base you wish to display the number in. Fortunately that's very easy to do. Below is an example of how one could print 32-bit hexadecimal numbers (I'll leave it as an exercise to you to strip the leading zeroes):
; Input:
; EAX = value to print
;
print_hex:
mov cx,8 ; print 8 hex digits (= 32 bits)
.print_digit:
rol eax,4 ; move the currently left-most digit into the least significant 4 bits
mov dl,al
and dl,0xF ; isolate the hex digit we want to print
add dl,'0' ; and convert it into a character..
cmp dl,'9' ; ...
jbe .ok ; ...
add dl,7 ; ... (for 'A'..'F')
.ok: ; ...
push eax ; save EAX on the stack temporarily
mov ah,2 ; INT 21H / AH=2: write character to stdout
int 0x21
pop eax ; restore EAX
loop .print_digit
ret
以10为基数或以2为基数的打印编号没有太大区别.只是当我们处理以2的幂(例如16或2)的基数时,我们可以使用shift(或在我的代码中旋转)和AND而不是除法和余数.
Printing numbers in base 10 or base 2 is not that much different. It's just that when we deal with bases that are powers of two (like 16 or 2), we can use shifts (or rotates in my code) and ANDs rather than division and remainders.
这篇关于使用EMU8086,是否可以直接打印变量的十六进制值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!