web-dev-qa-db-ja.com

アセンブリ言語で数値を印刷しますか?

mov al,10
add al,15

al」の値を印刷するにはどうすればよいですか?

23
Kristina Brooks

int 21hサービス2 を試しましたか? DLは印刷する文字です。

mov dl,'A' ; print 'A'
mov ah,2
int 21h

整数値を出力するには、整数を個々の文字に分解するループを作成する必要があります。値を16進数で印刷しても問題ない場合、これは非常に簡単です。

DOSサービスに頼れない場合は、 BIOS int 10hAL0Ehまたは0Ahに設定して使用することもできます。 。

26
mrkj

アセンブリ言語には、何かを直接印刷する手段はありません。アセンブラには、このような機能を提供するライブラリが付属している場合と付属していない場合があります。そうでない場合は、自分で作成する必要があり、非常に複雑な機能になります。また、物事を印刷する場所を決定する必要があります-ウィンドウで、プリンタで?アセンブラでは、これはあなたのために行われません。

7
anon

DOS EAXに保存された32ビット値を16進出力で出力(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..
4
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

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

参照: 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
0
user6849738

BIOSにアクセスできるブートローダーまたはその他のアプリケーションを作成していると仮定すると、次のことができます。

  • 16進バイトの最初の桁を分離する
  • 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   
0
Adrian Zhang

Win32 API MessageBoxを呼び出すのは幸運かもしれませんが、Win16がその特定のメソッドをサポートするかどうかは、他の誰かが答えることです。

0
Rushyo