ASM子程序在特定的位置在屏幕上打印彩色文本 [英] ASM subroutine to print coloured text at specific location on the screen

查看:220
本文介绍了ASM子程序在特定的位置在屏幕上打印彩色文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试着写一些ASM code会写一些文​​字,使用BIOS中断的显示。这code就会从引导扇区运行。

I'm trying to write some ASM code that will write some text to the display using BIOS interrupts. This code will run from the boot sector.

msgText DB "Hello"                  ;Text
msgCol  DB 0x07,0x08,0x09,0x0A,0x0B ;Colours
msgXY   DW 0x0E26                   ;Col/Row
msgLen  DB 0x05                     ;Length

该消息仅仅是你好,每个字母有不同的颜色。屏幕上的信息的位置是大致在中间,并且它具有为5的长度

The message is just "Hello", each letter having a different colour. The position of the message on the screen is roughly in the middle, and it has a length of 5.

我想写一个会写的任何的消息/彩色/ XY /长到屏幕上,但现在,让我们专注于这一个功能。

I want to write a function that will write any message/colour/xy/length to the screen, but for now, let's focus on this one.

print:
  MOV AH,0x02        ;Tell BIOS we want to set the cursor position
  MOV DX,[msgXY]     ;Tell BIOS where the cursor should go
  INT 0x10           ;Call BIOS video interrupt

  XOR ECX,ECX        ;Clear ECX
  MOV CX,[msgLen]    ;Set CX = msgLen

  MOV AH,0x0E        ;We want to print characters on the screen

  _loop:
    MOV EDX,msgText  ;Move address of text to EDX
    DEC ECX          ;Temporarily decrement ECX
    ADD EDX,ECX      ;Add ECX to the address of msgText
    INC ECX          ;Increment ECX back to what it was
    MOV AL,BYTE[EDX] ;Put the contents of the memory at EDX into AL

    MOV EDX,msgCol   ;Move address of text colour to EDX
    DEC ECX          ;Temporarily decrement ECX
    ADD EDX,ECX      ;Add ECX to the address of msgCol
    INC ECX          ;Increment ECX back to what it was
    MOV BL,BYTE[EDX] ;Put the contents of the memory at EDX into BL

    INT 0x10         ;Call BIOS video interrupt
    LOOP _loop
  RET

现在,我应该能够 CALL打印来调用它。

Now, I should be able to call this with CALL print.

(是的,我知道这版画你好倒退,我不担心,我可以只将其存储在内存中的东海生日贺,我不在乎 - 我有更大的问题)

(yes, I know this prints "Hello" backwards, I'm not worried about that. I can just store it in memory as "olleH", I don't care - I've got much bigger problems)

首先,在这里我设置 CX 行[msgLen] 会导致问题。我不得不硬code这使 CX 等于 0×05 ,我不知道为什么

First of all, the line where I set CX to [msgLen] causes problems. I've had to hardcode it to make CX equal to 0x05 and I'm not sure why.

其次,出于同样的原因presumably,当我尝试设置颜色code我有同样的问题,因为文本长度。如果我摆脱那些线条和刚硬code MOV BL,的0x0C ,然后正常工作。

Secondly, presumably for the same reason, when I try to set the colour code I have the same problem as the text length. If I get rid of those lines and just hardcode MOV BL,0x0C, then it works fine.

奇怪,然而, MOV DX,[msgXY] 部分似乎工作确定。

Oddly, however, the MOV DX,[msgXY] part seems to work OK.

我不能给出确切的任何问题,因为我一直在试图通过改变很多事情来解决这个问题了几个小时,和小东西我改变这里和那里似乎有非常联合国predictable结果。此外,调用各种BIOS中断似乎的变更的一些寄存器,这是很烦人的。此外,当我把东西往下压入栈和弹出回来出来以后,它是不同的,所以我一直在回避 PUSH POP 完全

I can't give any exact problems, because I've been trying to fix this for hours by changing lots of thing, and little things I change here and there seem to have very unpredictable results. Furthermore, calling various BIOS interrupts seems to change some of the registers, which is very annoying. Also, when I push stuff down onto the stack and pop it back out later, it's different, so I've been avoiding PUSH and POP altogether.

顺便说一句,我仍然在实模式下的x86在这个阶段。

By the way, I'm still in real mode x86 at this stage.

当然,我在做什么不能这么难。也许我只是需要一个咖啡。或者一些帮助? :)

Surely what I'm doing can't be this hard. Maybe I just need a coffee. Or some help? :)

推荐答案

好了,首先,已经定义的 msgLen 分贝。当你 MOV CX,[msgLen] ,装入两个字节。这是否会导致问题,要看是什么(如果有的话)是继 msgLen 。无论是定义 msgLen DW ,还是 MOV CL,[msgLen] (因为你已经得到了高位清零)。

Well, "first of all", you've defined msgLen as db. When you mov cx, [msgLen], you load two bytes. Whether this causes a problem depends on what (if anything) is after msgLen. Either define msgLen as dw, or do mov cl, [msgLen] (since you've got the upper bits cleared).

我没有看到其次类似的问题 - 你移动一个字节为8位寄存器。您正在使用32位寄存器,在本节似乎有些奇怪。 应该的工作,但它涨大了您的code位。 [DX] 是不是一个有效的16位寻址模式,当然 - 你必须使用 BX (它被用于其他目的), SI 。由于您使用的是32位寄存器, LEA EDX,[EDX + ECX - 1] 应该做你想要什么,而不暂时递减和递增 ECX 。 (但我不认为这会帮助你的问题)

I don't see a similar problem with "Secondly" - you're moving a byte into an 8-bit register. Seems strange that you're using 32-bit registers in this section. "Should" work, but it bloats up your code a bit. [dx] is not a valid 16-bit addressing mode, of course - you'd have to use bx (which is being used for other purposes), si, or di. Since you are using 32-bit registers, lea edx, [edx + ecx - 1] should do what you want without temporarily decrementing and incrementing ecx. (but I don't think that'll help your problem)

预期某些BIOS中断会改变的寄存器。无论是怪异与否取决于哪些中断正在这样做。他们大多不知道。不能够弹出相同的值,你 ED是怪异。要么你已经发现了一个CPU的bug或者你做错了什么。猜猜这是可能性更大。 :)他们是有用的,所以这是一个耻辱,不能够使用他们。你不显示第一幕你的启动扇区,在那里你初始化 DS ES ,并成立了一个明智的栈 - ?也许有一个问题存在

It is expected that certain BIOS interrupts would alter registers. Whether it's weird or not depends on which interrupts are doing it. Mostly they don't. Not being able to pop the same value you pushed is weird. Either you've discovered a CPU bug or you're doing something wrong. Guess which is more likely. :) They're useful instructions, so it's a shame not to be able to use 'em. You don't show "act I" of your bootsector, where you initialize ds and es and set up a sensible stack - perhaps there's a problem there?

你有没有看INT 10H / 13H?我认为它会做你想要什么(彩虹文本)。这是一个奇怪的中断,因为它希望该文本的地址是在 ES:BP ,但很有用。另一种方法是戳字符和颜色直接画面存储器在B800h:XXXX - 字符一个字节和用于彩色一个字节

Have you looked at int 10h/13h? I think it'll do what you want ("rainbow" text). It's a weird interrupt, in that it expects the text address to be in es:bp, but useful. Another approach is to poke character and color directly to "screen memory" at B800h:xxxx - one byte for character and one byte for color.

一个引导扇区是不是特别容易写。如果你有真正的DOS系统(甚至DOSBox中),它可能有助于试用你的程序作为一个.com文件(其中DEBUG可用)的一部分。一个引导扇区是从DOS环境不同,所以它不会解决你所有的问题,但可能有助于缩小下来。

A bootsector isn't particularly easy to write. If you've got real dos available (or even Dosbox), it may help to "try out" your routines as part of a .com file (where DEBUG is available). A bootsector is a different environment from dos, so it won't solve all your problems, but may help to narrow it down.

咖啡可以帮助,但主要是......挺住!

Coffee may help, but mostly... Courage!

最佳,
弗兰克

Best, Frank

这篇关于ASM子程序在特定的位置在屏幕上打印彩色文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆