我有我的汇编代码的问题。 我想打印存储在寄存器CX数,但是当我试图将其打印出来,它打印的ASCII字符,而不是ASCII数字,所以我决定写一个程序来的ASCII字符转换为ASCII值。 问题是,当我尝试调用该程序,该程序冻结和我必须重新启动DOSBox中。 有谁知道什么是错用此代码? 谢谢。
P4 PROC
MOV AX,CX ;CX = VALUE THAT I WANT TO CONVERT
MOV BX,10
ASC2:
DIV BX ;DIV AX/10
ADD DX,48 ;ADD 48 TO REMAINDER TO GET ASCII CHARACTER OF NUMBER
PUSH AX ;SAVE AX
MOV AH,2 ;PRINT REMAINDER STORED IN DX
INT 21H ;INTERRUP
POP AX ;POP AX BACK
CMP AX,0
JZ EXTT ;IF AX=0, END OF THE PROCEDURE
JMP ASC2 ;ELSE REPEAT
EXTT:
RET
P4 ENDP
像这样将工作打印十进制值(新代码为小写)更好:
mov byte [buffer+9],'$'
lea si,[buffer+9]
MOV AX,CX ;CX = VALUE THAT I WANT TO CONVERT
MOV BX,10
ASC2:
mov dx,0 ; clear dx prior to dividing dx:ax by bx
DIV BX ;DIV AX/10
ADD DX,48 ;ADD 48 TO REMAINDER TO GET ASCII CHARACTER OF NUMBER
dec si ; store characters in reverse order
mov [si],dl
CMP AX,0
JZ EXTT ;IF AX=0, END OF THE PROCEDURE
JMP ASC2 ;ELSE REPEAT
EXTT:
mov ah,9 ; print string
mov dx,si
int 21h
RET
buffer: resb 10
代替印刷的每个字符的直接将其添加的字符以相反的顺序的缓冲器。 对于值123,将在缓冲液中添加“3”,在缓冲液[8],“2” [7]和“1”,在缓冲器[6] - 因此如果然后打印字符串起始缓冲液+ 6你“123 ”。
我使用NASM语法,但希望它应该足够明确。
正如迈克尔已经写在他的代码,你需要清除DX,即让它0你把之前。
但如果你问我,如果你只需要显示ASCII格式的数字(如果你想显示的号码没有得到一个笑脸)。 该值在内部转换为ASCII可以说是相当不方便。
你为什么不只是使用在具有数字的所有ASCII值,程序开始定义了一个数组,并挑选一个是对应的。
对于如。 DB arr '0123456789'
,并比较与特定位置的每个编号并打印一个。 这是一个很长的时间,因为我在8086已经编码,但我记得使用这个逻辑,这需要我去打印十六进制数的ASCII值的节目。 所以我用一个数组,有0123456789ABCDEF
它完美地工作。
只是我的两分钱。 既然你只想要的结果。 其实并不重要,你如何计算它。
认为我应该发布一个更新到这一点。 这篇文章真的帮了我寻找一种方式来获得键输入PHP CLI脚本。 我找不到任何地方在Windows / DOS的解决方案,所以我选择了一个外部程序。
我使用的是真正的老版本A86汇编这样的代码是非常基本的。
(和我怎么关闭“运行代码片段”?)
;Key input for scripts that can use some "shell" function. ;Waits for a keypress then returns a string "key:scan" ;if "key" is 0 then you can check "scan" for arrow keys ;or other non-ASCII keys this way. mov ah,0 int 16h push ax mov ah,0 mov cx,ax call ASC mov dx,':' call COUT pop ax shr ax,8 mov ah,0 mov cx,ax call ASC jp EXIT COUT: mov ah,2 int 21h ret STROUT: mov ah,9 mov dx,si int 21h ret ASC: mov byte [buffer+9],'$' lea si,[buffer+9] mov ax,cx mov bx,10 ASC_LOOP: mov dx,0 div bx add dx,48 dec si mov [si],dl cmp ax,0 jz STROUT jmp ASC_LOOP EXIT: mov ah,4ch int 21h ret buffer: db " " ; 10 spaces. no "resb" in my assembler.
样本PHP脚本来测试它:
<?php function getKey() { return shell_exec("getkey.com"); } print "Press [ESC] to exit.\n\n"; $key = ""; while (ord($key) != 27) { $getch = explode(":",getKey()); $key = chr($getch[0]); $scan = $getch[1]; if (ord($key) != 0) { print $key; } else { print "SCAN:$scan\n"; } } ?>
诚然毕竟是说,做我意识到我可以在C ++中也做了同样的事情。 但是我学到了很多关于ASM这一次。
所以,再次感谢乡亲!
这里的打印数量以及测试代码
.186
.model SMALL
.STACK 100h
.data
HelloMessage db 'Hello World', 13, 10, '$'
SuperNumber dw 13565
.code
; Writes word number from AX to output
; Usage
; .186
; ....
; mov ax, 13444
; call PRINT_NUMBER
PRINT_NUMBER PROC NEAR ; Outputs integer word number stored in AX registry. Requires CPU
; Save state of registers.
PUSHA ; Save all general purpose registers
PUSH BP ; We're going to change that.
; we need variables
; word number; 2 bytes
; byte digitsCount; 1 byte
; reserving space for variables on stack (3 bytes)
mov bp, sp; ; bp := address of the top of a stack
sub sp, 3*8 ; allocate 3 bytes on stack. Addresses of variables will be
; number: WORD PTR [rbp - 2*8]
; digitsCount: BYTE PTR [rbp - 3*8]
; Getting digits
; number = ax;
; digitsCount = 0;
; do
; {
; push number%10;
; digitsCount++;
; number = number / 10;
; }
; while (number > 0)
mov WORD PTR [bp - 2*8], ax ; number = ax;
mov BYTE PTR [bp - 3*8], 0 ; digitsCount = 0;
getDigits: ; do
mov ax, WORD PTR [bp - 2*8]; number/10: ax = number / 10, dx: number % 10
;cwd
mov dx, 0
mov bx, 10
div bx
push dx ; push number%10
mov WORD PTR[bp - 2*8], ax; number = number/10;
inc byte PTR[bp - 3*8] ; digitsCount++;
cmp WORD PTR[bp - 2*8], 0; compare number and 0
je getDigitsEnd ; if number == 0 goto getDigitsEnd
jmp getDigits ; goto getDigits;
getDigitsEnd:
mov ah, 9
mov dx, offset HelloMessage
int 21h
;while (digitsCount > 0)
;{
; pop digit into ax
; print digit
; digitsCount--;
;}
printDigits:
cmp BYTE PTR[bp - 3*8], 0; compare digits count and 0
je printDigitsEnd ; if digitsCount == 0 goto printDigitsEnd
pop ax ; pop digit into al
add al, 30h ; get character from digit into al
mov ah, 0eh ; wanna print digit!
int 10h ; BIOS, do it!
dec BYTE PTR[bp - 3*8] ; digitsCount--
jmp printDigits ; goto printDigits
printDigitsEnd:
; Deallocate local variables back.
mov sp, bp
; Restore state of registers in reverse order.
POP BP
POPA
; Exit from procedure.
RET
PRINT_NUMBER ENDP
start:
mov ax, @data
mov ds, ax
mov ah, 9
mov dx, offset HelloMessage
int 21h
mov ax, 64454
call Print_Number
mov ah, 4ch
int 21h
end start