어셈블리 언어로 숫자를 인쇄 하시겠습니까?
문제
mov al,10
add al,15
'의 가치를 어떻게 인쇄합니까?알'?
해결책
당신은 시도 했습니까? int 21h
서비스 2? DL
인쇄 할 캐릭터입니다.
mov dl,'A' ; print 'A'
mov ah,2
int 21h
정수 값을 인쇄하려면 정수를 개별 문자로 분해하려면 루프를 작성해야합니다. 16 진수로 값을 인쇄해도 괜찮다면 이것은 매우 사소합니다.
DOS 서비스에 의존 할 수 없다면 바이오스 int 10h
~와 함께 AL
로 설정 0Eh
또는 0Ah
.
다른 팁
어셈블리 언어에는 인쇄 할 수있는 직접적인 수단이 없습니다. 어셈블러에는 그러한 시설을 공급하는 도서관이 있거나 제공되지 않을 수도 있습니다. 그렇지 않으면 직접 작성해야하며, 상당히 복잡한 기능이 될 것입니다. 또한 창문, 프린터에 물건을 인쇄 할 위치를 결정해야합니까? 어셈블러에서는이 중 어느 것도 당신을 위해 이루어지지 않습니다.
DOS Print 32 비트 값은 16 진 출력으로 EAX에 저장된 비트 값 (80386+)
(64 비트 OS에서 dosbox를 사용)
.code
mov ax,@DATA ; get the address of the data segment
mov ds,ax ; store the address in the data segment register
;-----------------------
mov eax,0FFFFFFFFh ; 32 bit value (0 - FFFFFFFF) for example
;-----------------------
; convert the value in EAX to hexadecimal ASCIIs
;-----------------------
mov di,OFFSET ASCII ; get the offset address
mov cl,8 ; number of ASCII
P1: rol eax,4 ; 1 Nibble (start with highest byte)
mov bl,al
and bl,0Fh ; only low-Nibble
add bl,30h ; convert to ASCII
cmp bl,39h ; above 9?
jna short P2
add bl,7 ; "A" to "F"
P2: mov [di],bl ; store ASCII in buffer
inc di ; increase target address
dec cl ; decrease loop counter
jnz P1 ; jump if cl is not equal 0 (zeroflag is not set)
;-----------------------
; Print string
;-----------------------
mov dx,OFFSET ASCII ; DOS 1+ WRITE STRING TO STANDARD OUTPUT
mov ah,9 ; DS:DX->'$'-terminated string
int 21h ; maybe redirected under DOS 2+ for output to file
; (using pipe character">") or output to printer
; terminate program...
.data
ASCII DB "00000000",0Dh,0Ah,"$" ; buffer for ASCII string
소프트웨어 상호 작용을 사용하지 않고 대체 문자열 출력 :
;-----------------------
; Print string
;-----------------------
mov ax,0B800h ; segment address of textmode video buffer
mov es,ax ; store address in extra segment register
mov si,OFFSET ASCII ; get the offset address of the string
; using a fixed target address for example (screen page 0)
; Position`on screen = (Line_number*80*2) + (Row_number*2)
mov di,(10*80*2)+(10*2)
mov cl,8 ; number of ASCII
cld ; clear direction flag
P3: lodsb ; get the ASCII from the address in DS:SI + increase si
stosb ; write ASCII directly to the screen using ES:DI + increase di
inc di ; step over attribut byte
dec cl ; decrease counter
jnz P3 ; repeat (print only 8 ASCII, not used bytes are: 0Dh,0Ah,"$")
; Hint: this directly output to the screen do not touch or move the cursor
; but feel free to modify..
PRINT_SUM PROC NEAR
CMP AL, 0
JNE PRINT_AX
PUSH AX
MOV AL, '0'
MOV AH, 0EH
INT 10H
POP AX
RET
PRINT_AX:
PUSHA
MOV AH, 0
CMP AX, 0
JE PN_DONE
MOV DL, 10
DIV DL
CALL PRINT_AX
MOV AL, AH
ADD AL, 30H
MOV AH, 0EH
INT 10H
PN_DONE:
POPA
RET
PRINT_SUM ENDP
Win16이 특정 방법이 다른 사람이 대답하는지 여부는 Win32 API의 Messageboba를 호출하는 행운이있을 수 있습니다.
ah = 09 ds : dx = "$"로 끝나는 문자열에 대한 포인터
returns nothing
- outputs character string to STDOUT up to "$"
- backspace is treated as non-destructive
- if Ctrl-Break is detected, INT 23 is executed
ref : http://stanislavs.org/helppc/int_21-9.html
.data
string db 2 dup(' ')
.code
mov ax,@data
mov ds,ax
mov al,10
add al,15
mov si,offset string+1
mov bl,10
div bl
add ah,48
mov [si],ah
dec si
div bl
add ah,48
mov [si],ah
mov ah,9
mov dx,string
int 21h
BIOS에 액세스 할 수있는 부트 로더 또는 기타 응용 프로그램을 작성한다고 가정하면 다음은 다음과 같이 할 수있는 일에 대한 대략적인 스케치가 있습니다.
- 육각 바이트의 첫 번째 숫자를 분리하십시오
- 9보다 큰 경우 (예 : 0x0a ~ 0x0f) 10을 빼고 (0 ~ 5로 축소) 'A'(0x41)를 추가하십시오.
- 9보다 작거나 같으면 (예 : 0x00 ~ 0x09) '0'을 추가하십시오.
- 다음 16 진수로 반복하십시오.
다음은 이것의 구현입니다.
; Prints AL in hex.
printhexb:
push ax
shr al, 0x04
call print_nibble
pop ax
and al, 0x0F
call print_nibble
ret
print_nibble:
cmp al, 0x09
jg .letter
add al, 0x30
mov ah, 0x0E
int 0x10
ret
.letter:
add al, 0x37
mov ah, 0x0E
int 0x10
ret
Winapi 기능을 호출하십시오 (Win-Application을 개발하는 경우)
; good example of unlimited num print
.model small
.stack 100h
.data
number word 6432
string db 10 dup('$')
.code
main proc
mov ax,@data
mov ds,ax
mov ax,number
mov bx ,10
mov cx,0
l1:
mov dx,0
div bx
add dx,48
push dx
inc cx
cmp ax,0
jne l1
mov bx ,offset string
l2:
pop dx
mov [bx],dx
inc bx
loop l2
mov ah,09
mov dx,offset string
int 21h
mov ax,4c00h
int 21h
main endp
end main
mov al,3 ;print ♥
mov dl,al
;call print service(2) to print from dl
mov ah,2
int 21h
;return to DOS
mov ah,76 ;76 = 4ch
int 21h ;call interrupt