views:

627

answers:

4

I've just started using assembly language (felt like learning something new), and have run into a few questions (so far) that all the tutorials I've been looking through don't answer, or are too old to know.

1) I've tried a few searches (maybe I just don't know the right keywords), but I can't find an updated list of graphics modes for changing screen resolutions, etc. The best I've found is: Assembler Tutorial, and I'd hardly think that 640x480 is the best resolution assembly language can use. Does anyone know of a more updated tutorial I can use?

Edit: Interrupt 10h is old, and doesn't quite support more than 640x480

2) Is it possible to "mov" a value from a variable to another variable without moving it to a register first? Example:

jmp start
  n1     dw 0
  n2     dw 0
  res    dw 0
start:
  mov n1,5
  mov n2,6
  mov res,n1
  add res,n2
...etc...

Edit: It is not possible. You cannot go from memory to memory without using registers.

3) Going with question 1, is there a way to detect what graphics mode a user is currently using, so that I can change it, and change it back after? (I assume there is, but am not sure how to do it.)

Edit: Need to query OS for graphics settings.

+2  A: 

Regarding your first question, interrupt 10 is very old, and likely not used beyond resolutions of 640x480. A different part of the software stack is now used; i.e., you would have to interrogate Windows to get the current screen resolution.

Robert Harvey
Is there another interrupt that is newer than 10, but does something similar? I don't know if you would know, but how does Windows do it? I can only assume that they would use assembly, or a language that compiles to assembly... Hence why I figured Assembly could do it.
Sivvy
+2  A: 

This rather verbose post contains a lot of details of how to use assembler to drive DirectX in Windows. DirectX is the key API family for graphics these days, you won't come far using DOS-era interrupts and programming the VGA framebuffer directly.

unwind
+2  A: 

For questions #1 and #3, look into the VESA BIOS Extensions. This was something of a standard for dealing with "Super VGA" modes, popular in the 90s.

As for #2, in general the answer is no, you can't MOV memory to memory. But it's not strictly true: there MOVS (move string), which moves a byte, word, or dword from DS:SI to ES:DI. Usually this instruction is used in conjunction with a REP prefix to move blocks of memory. Also, assuming you have a stack set up, you can move memory-to-memory without clobbering a register by pushing and popping:

PUSH [mem1]
POP  [mem2]
I. J. Kennedy
+1  A: 

Interrupt 10h is basically an operating system function call (actually it runs BIOS code). Internally, it reads/writes video memory as well as various registers on the graphics card. To get an idea of what sort of stuff happens "within" interrupt 10h, check this out.

When you run a DOS program under Windows, it is run in a virtual DOS machine. Windows doesn't actually let it touch the graphics card but lets it play with a virtual one. Usually this only extends as far as VGA screen modes (and sometimes only text mode), i.e. what you have is a virtual VGA card (not a modern graphics card). For this reason, in 16-bit assembly language under Windows, you just can't use the full capabilities of modern graphics cards.

Yes, sure, assembly language can let you do anything the graphics card can do. But only if either:

  • your program has unrestricted access to the graphics hardware (e.g. you're writing a Windows or Linux device driver, or are executing in pure DOS, or your own kernel), or
  • your program goes through the appropriate operating system interface.

If you're still interested in assembly language, I would suggest you try to write a toy kernel. Doing this, you'll learn a mountain of things.

Leave a comment if you want further information.

Artelius
Thanks for the input... I think I might take a look at playing with a kernel. Is it difficult for a beginner?
Sivvy
Of course it's difficult! But it's very rewarding, if you enjoy solving tough challenges. One way to start is by putting some code in the boot sector of a floppy disk or flash drive and booting a computer from it. And slowly expand its functionality. Get yourself a copy of HelpPC (good reference for BIOS interrupts, data formats and memory use), and check out http://en.wikibooks.org/wiki/X86_Assembly/Bootloaders
Artelius