|
发表于 2018-11-23 17:11:17
|
显示全部楼层
我知道可能已经晚了,但是我写完了,那就贴出来吧
assume cs:code, ds:data
data segment
buffer db 512 dup(0)
stack db 512 dup(0)
stack_top:
data ends
code segment
; void PutChar(uint8_t x, uint8_t y, char ch, uint8_t attr);
PutChar:
push bp
mov bp, sp
push di
push es
mov ax, 0b800h
mov es, ax
mov dl, [bp + 6] ; y
mov al, 160
mul dl
mov di, ax
mov dl, [bp + 4] ; x
mov al, 2
mul dl
add di, ax
mov al, [bp + 8] ; ch
mov ah, [bp + 10] ; attr
mov es:[di], ax
mov bh, 0 ; 显示页码
mov dh, [bp + 6] ; y
mov dl, [bp + 4] ; x
add dl, 1
mov ah, 2 ; 设置光标位置
int 10h
pop es
pop di
mov sp, bp
pop bp
ret
; void PutString(uint8_t x, uint8_t y, char *str, uint8_t attr);
PutString:
push bp
mov bp, sp
push bx
push si
push di
mov si, [bp + 4] ; x
mov di, [bp + 6] ; y
mov bx, [bp + 8] ; str
@@:
cmp byte ptr [bx], 0
je @F
push [bp + 10] ; attr
xor ah, ah
mov al, [bx]
push ax ; ch
push di ; y
push si ; x
call PutChar
add sp, 8
inc si
inc bx
jmp @B
@@:
pop di
pop si
pop bx
mov sp, bp
pop bp
ret
; void NumberToString(uint16_t number, char *buffer);
NumberToString:
push bp
mov bp, sp
push bx
push si
push di
mov di, [bp + 6] ; buffer
mov ax, [bp + 4] ; number
xor dx, dx
mov cx, 16
@@:
div cx
mov dh, dl
add dl, '0'
cmp dh, 10
jb @1
mov dl, dh
sub dl, 10
add dl, 'A'
@1:
mov [di], dl
inc di
xor dx, dx
cmp ax, 0
jne @B
mov byte ptr [di], 0 ; '\0'
; 下面翻转字符串
dec di
mov si, [bp + 6] ; buffer
@@:
cmp si, di
jge @F
mov ah, [si]
mov al, [di]
mov [si], al
mov [di], ah
inc si
dec di
jmp @B
@@:
pop di
pop si
pop bx
mov sp, bp
pop bp
ret
; uint16_t strlen(char *str);
strlen:
push bp
mov bp, sp
push bx
mov bx, [bp + 4] ; str
xor ax, ax
@@:
cmp byte ptr [bx], 0
je @F
inc ax
inc bx
jmp @B
@@:
pop bx
mov sp, bp
pop bp
ret
; void strcpy(char *dest, char *src);
strcpy:
push bp
mov bp, sp
push si
push di
mov di, [bp + 4] ; dest
mov si, [bp + 6] ; src
@@:
mov al, [si]
mov [di], al
inc si
inc di
cmp al, 0
jne @B
pop di
pop si
mov sp, bp
pop bp
ret
; 设置字符串长度为num个字符,如果字符串长度不够,在字符串前面添加字符'0'
; 如果字符串长度大于等于num个字符则什么也不做
; void FormatString(char *str, uint16_t num);
FormatString:
push bp
mov bp, sp
sub sp, 100
push bx
mov bx, [bp + 4] ; str
push bx
call strlen
add sp, 2
cmp ax, [bp + 6] ; num
jae FormatString_done
push ax ; 保存str的长度,之后要用
push bx
lea ax, [bp - 100]
push ax
call strcpy
add sp, 4
mov cx, [bp + 6] ; num
pop ax ; 在这里使用之前保存的str长度
sub cx, ax
@@:
mov byte ptr [bx], '0'
inc bx
dec cx
cmp cx, 0
jne @B
lea ax, [bp - 100]
push ax
push bx
call strcpy
add sp, 4
FormatString_done:
pop bx
mov sp, bp
pop bp
ret
; uint16_t getchar(void);
getchar:
push bp
mov bp, sp
mov ah, 0
int 16h
xor ah, ah
mov sp, bp
pop bp
ret
; void ClearScreen(void);
ClearScreen:
push bp
mov bp, sp
push di
push es
mov ax, 0b800h
mov es, ax
xor di, di
mov cx, 80 * 25
mov ax, 0720h
cld
rep stosw
pop es
pop di
mov sp, bp
pop bp
ret
start:
mov ax, data
mov ss, ax
mov sp, offset stack_top
mov ds, ax
call ClearScreen
xor bx, bx
xor si, si ; x
xor di, di ; y
@@:
cmp bx, 0FFh
ja @F
mov ax, 04h
push ax ; attr
push bx ; ch
push di ; y
mov ax, si
mov cl, 7 ; 每列7个字符对齐
mul cl
xor ah, ah
push ax ; x
call PutChar
add sp, 8
mov ax, offset buffer
push ax ; buffer
push bx ; number
call NumberToString
add sp, 4
mov ax, 2
push ax ; num
mov ax, offset buffer
push ax ; str
call FormatString
add sp, 4
mov ax, 02h
push ax ; attr
mov ax, offset buffer
push ax ; str
push di ; y
mov ax, si
mov cl, 7
mul cl
xor ah, ah
inc ax
push ax ; x
call PutString
add sp, 8
inc di
cmp di, 25 ; 每行25个字符
jb @1
inc si
xor di, di
@1:
inc bx
jmp @B
@@:
call getchar
mov ax, 4c00h
int 21h
code ends
end start
最后,附上C代码#include <stdio.h>
#include <windows.h>
static void HideCursor(void)
{
CONSOLE_CURSOR_INFO cci = {100, FALSE};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
}
static void GotoXY(size_t x, size_t y)
{
COORD coord = {(SHORT)x, (SHORT)y};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void PutChar(size_t x, size_t y, char ch, WORD color)
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
DWORD NumberOfAttrsWritten;
GotoXY(x, y);
putchar(ch);
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
csbi.dwCursorPosition.X -= 1;
FillConsoleOutputAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color, 1, csbi.dwCursorPosition, &NumberOfAttrsWritten);
}
int main(void)
{
const int WIDTH = 8;
const int HEIGHT = 25;
HideCursor();
int x = 0;
int y = 0;
for(int i = 0x00; i <= 0xFF; ++i)
{
PutChar(x * WIDTH, y, i, FOREGROUND_GREEN);
GotoXY(x * WIDTH + 1, y);
printf("%.2X", i);
++y;
if(y >= HEIGHT)
{
y = 0;
++x;
}
}
getchar();
return 0;
}
|
|