Jump to content
xisto Community

vizskywalker

Members
  • Content Count

    1,084
  • Joined

  • Last visited

Posts posted by vizskywalker


  1. Okay, I'm going to address the second and third points first. It's a new install of XP with reformatting the HD. Even though HP owns Compaq, the Compaq site still provides support for Compaw computers, and the driver search on HP takes me to the same site for driver downloads as the Compaq site. I just (after making that post) reinstalled Windows, and now the network card works fine (I'm on it now). I haven't tried the graphics driver yet, but I will let you know the results as soon as I do. Thanks for your help.


  2. Okay, this seemed like the best place to post this. I'm trying to update my Compaq Presario 1800T notebook to Windows XP, and half of the drivers I need to install say "The data is invalid". This is the situation for the graphics driver as well as my linksys wireless g adapter. I tried updating the bios, which windows recognizes as a "System device" with a yellow exclamation mark, but the update provided by compaw does not match the type of bios the motherboard has (according to the install utility). Any help here would be appreciated.


  3. Sorry this one came out so late, busy week. As recompense, there will be an extra two this week, the next one, and then a VGA intro. Say thank you to my history teacher.

     

    Also, in case you've heard about this. The assembler I'm working on is coming along well. I need suggestions for what you'd like to see in an assembler as well as people willing to test it. (I'll be doing extensive Alpha testing, so I promise with a 99.5% guarantee that it won't crash your computer.) Currently it is for windows only, sorry Linux users. And Mac people, I haven't forgotten about you, but I don't have access to an Apple computer, so I can't test anything I would pass on to you, so once I get an Apple, I will write tutorials for you guys. And without further Adieu (yes purposely misspelled, it's a lame pun, but I'm writing these things for you so back off): the tutorial:

     

    Okay, if you missed the previous tutorial, you can catch it here.

     

    Note: This tutorial is updated for the following OS/Compiler combinations

    1: Windows/TASM

    2: Windows/FASM

    3: Linux/NASM

    Others are forthcoming.

     

    Last week we ended with a very simple Hello World Program. Today is going to build a little bit off of the code used in that program.

     

    But first, something rarely covered this early on in an assembly tutorial set, and at the request of the wonderful osknockout, memory in depth.

     

    As stated last week, memory in the computer is stored in segments and offsets. Each segment is 64kb long with a new segment starting every 16 bytes. This leads to overlapping segments, and means the last segments do not contain a full complement of 64kb.

     

    Now, the question that should be on your mind is, "So what does this have to do with my programs?" The answer is, in short, everything. A program without variables is worthless to a user, and variables are stored in memory.

     

    Note: The example structure I am going to be working with is a Windows .exe file, however, the principles I will cover apply to everything.

     

    When an .exe file is loaded by Windows, several segments are defined by Windows to have a special meaning. These are the data segment, the code segment, and the stack segement.

     

    The data segment is the segment at which all preset data in a program can be found. While it is possible to access this data using another segment with a greater offset, this is the standard segment address for the data. The reason this predefined segment is important, is that if you look at the binary of an .exe file, the data directly follows the code with no separation. This segment is set up so the program will know where to look for the data.

     

    The code segment serves the exact same purpose as the data segment, except for the the information that is stored there. The code segment contains, as the name suggests, all of the instructions that the program must execute. The code segment identifier for the .exe file also labels the entry point, where the program should begin execution of instructions.

     

    The stack is a special part of a program. It is like an extra data segment that has special rules. Items are placed on the stack in a last-in first-out method, like stacking plates. (See figure 1)

     

    Figure 1:

    Note: The data is vertical to help illustrate last in first off

    Offset Before First action Second action Third action Fourth action

    0 [] [] [] [] []

    1 [] [] [] [] []

    2 [] [] [] [] []

    3 [] [] [] [] []

    4 [] [] [] [] []

    5 [] [] [] [] []

    6 [] [] [] [] []

    7 [] [] [] [] []

    8 [] [] [22] [] []

    9 [] [55] [55] [55] []

     

    As the above figure illustrates, data is put on the stack at the end of the stack first. This means that sp, the stack pointer, gets decremented instead of incremented everytime something goes on the stack.

     

    Okay, on to accessing memory. Remember last tutorial where I said that variables were declared by labeling a memory offset? Well, here's how you access those varibales. In TASM, which is different from other assemblers, directly stating the label means access he data pointed to by the label. (See figure 2). However, sometimes we need the memory offset of the data, for this purpose we can use either the "offset" keyword or enclose the label in square brackets ([label]). (See figure 2). In FASM and NASM, the situation is reversed. Stating a label directly access its memory offset, while enclosing it in square brackets accesses its data. (Remember, the "db" command defines a label and data)

     

    Figure 2:

     

    TASM FASM/NASM

    Label db Label db

    Offset: 0 1 2 3 4 5 6 7 Offset: 0 1 2 3 4 5 6 7

    Data: [A][C][D][E][F][G][H] Data: [A][C][D][E][F][G][H]

     

    mov al, Label ;al now contains "A" mov ax, Label ;ax now contains 0

    mov ax, [Label] ;al now contains 0 mov al, [Label] ;al now contains A

     

    Note: I went from a to c instead of a to d because a b in square brackets causes bold text.

     

    The astute observers of you (by which I mean those of you not operating on less than 6 hours of sleep, by which I most likely mean no one, we're human after all, except for you, yes you, the one from Mars, sorry I got carried away) noticed that we used ax to store the offset and al to store the data. This leads to an interesting question: why? The answer lies in how we defined the data. Segments and offsets are always 16 bits, so they require a 16 bit register, such as ax. However, we used "db" to define the data. "Db" stands for declare byte, so the data must be accessed as a byte. "Db" is actually a special form of what I like to call the "d" command (this command technically doesn't exist, I use it here because I will then be able to reference it later which will be helpful). The "d" command has many different forms: "db", "dw", "dd", "dq", "dt". They stand for declare byte, declare word, declare double word, declare quad word, declare tenbyte respectively.

     

    Perhaps now would be a good time to define word, double word, etc.

    A word is simply two bytes, a doubleword is exactly that, so four bytes, a quadword is four words or eight bytes, and a tenbyte is ten bytes.

     

    The way you define data determines how it must be accessed. If you define something as a byte, it must always be dealt with as a byte. If it is defined as a word, it must always be dealt with as a word. So how can we use "db" to define multiple bytes, like a string? In realit the "d" command does two things. 1) It defines a label of size byte, word, etc. 2) It places data into the code. The second function of the "d" command is not really related to the first.

     

    Okay, I think that about covers memory. On to arithmatic.

     

    First, the "add" command. This commad is pretty basic, it adds things. The format is as follows:

     

    add register, {memory, immediate, register}

     

    Note: the {} means any one of the options in the brackets.

    In case you were wondering, an immediate is simply a number written into the code.

     

    The "add" command adds whatever the second part is to the first part and stores the result in the first part. So in "add ax, 1", whatever is in ax gets increased by one and stored in ax. Users of higher level languages probably know a special name for what we just did: incrementing. Assembly has the ability to increment using the "inc" command. "Inc" simply is followed by the register you wish to increment.

     

    Next up is the "sub" command. Guess what, it works exactly like the "add" command, except it subtracts. There is also an equivalent for incrementing here: decrementing. The command for this is "dec", and it works the same way as "inc".

     

    Multiplication and division are a bit harder. Multiplication, the "mul" command takes one parameter, the register to multiply by. The other register is either al, ax, or eax depending on the size of the multiplying register. Acessing the result is also tricky. If the size is one byte, al is used and the result is found in ax. If the size is a word, ax is used, and the result is in ax:dx with ax being the higher part and dx being the lower part. If the size is a double word, then eax is used, and the result is found in eax:edx with eax being the high part and edx being the low part.

     

    Division, the "div" command, is similar to "mul". Once again, it only takes only one parameter, the register containing the value to divide by. If this register is a byte, ax is divided by it, and the result is put in al with the remainder in ah. If the register is a word, then ax:dx (ax high part, dx low part) is divided by it, and the result is found in ax with the remainder in dx. If the register is a doubleword, then eax:edx (eax high part, edx low part; whenever you see xxxx:xxxx, the left part is always the high part and the right is always the low part, add them together to get the true value. The exception is when dealing with memory when the left is the segment and the right is the offset) is divided by it, and the result is stored in eax with the remainder in edx.

     

    Now, with some basic math and the ability to use variables, let us create a program.

     

    Disclaimer: Once again, the program is designed for TASM, Windows FASM adjustments follow the code. I don't have Linux because I need Windows to be compatible with the rest of the house and don't have enough space on my hard drive

    for a double boot, so the Linux version is unprovided. Line numbers are for reference only, remove them before compiling.

     

    ---Begin Copy Next Line---

    1: .MODEL SMALL ;define the type of program

    2: .STACK 200h ;define the stack size

    3: .386 ;state the use of 386 instructions

    4:

    5: .DATA ;define the data segment

    6: Divide db ? ;divide is a byte to hold the result of division. the ?

    7: ;means don't specify a value at compilation

    8: Remainder db ? ;to hold the remainder form the division

    9: Multiply dw ? ;multiply is a word to hold the result of a multiplication

    10: Addition db 01h ;initial value for addition (1)

    11: Subtraction db 40h ;initial value for subtraction (64)

    12:

    13: .CODE ;define the code segment

    14:

    15: Start: ;start the program

    16: mov ax, seg Multiply ;move the data segment to the accumulator

    17: mov ds, ax ;move data segment to data segment register

    18: mov es, ax ;move data segment to es register

    19:

    20: mov al, Addition ;set al equal to addition

    21: add al, 30h ;add 48 to al

    22: mov ah, 0eh ;prepare for function 100eh, teletype character (see 23: ;Ralph Brown's Interrupt List)

    24: mov bh, 00h ;page 0

    25: mov bl, 07h ;color light grey

    26: int 10h ;print it

    27:

    28: mov ah, 00h ;once again, pause until a key is pressed

    29: int 16h

    30:

    31: mov al, Subtraction ;mov the value in subtraction to al

    32: dec al ;subtract 1 from al

    33: mov ah, 0eh ;prepare for function 100eh, teletype character (see 34: ;Ralph Brown's Interrupt List)

    35: mov bh, 00h ;page 0

    36: mov bl, 07h ;color light grey

    37: int 10h ;print it

    38:

    39: mov ah, 00h ;once again, pause until a key is pressed

    40: int 16h

    41:

    42: mov al, 0eeh ;set al to 16

    43: mov bl, 60h ;set bl to 3

    44: mul bl ;multiply al and bl store result in ax

    45: mov Multiply, ax ;store the result in Multiply

    46:

    47: mov ax, 1301h ;Interrupt 13h

    48: mov bx, 07h ;page 0, color 7

    49: mov cx, 02h ;two charcters

    50: mov dx, 00h ;start at top left

    51: mov bp, offset Multiply ;move the offset of Multiply to base pointer

    52: int 10h

    53:

    54: mov ah, 00h ;once again, pause until a key is pressed

    55: int 16h

    56:

    57: mov ax, 2141h ;set al to 16

    58: mov bl, 80h ;set bl to 3

    59: div bl ;multiply al and bl store result in ax

    60: mov Divide, al ;store the result in Multiply

    61: mov Remainder, ah

    62:

    63: mov ax, 1301h ;Interrupt 13h

    64: mov bx, 07h ;page 0, color 7

    65: mov cx, 02h ;two charcters

    66: mov dx, 00h ;start at top left

    67: mov bp, offset Divide ;move the offset of Divide to base pointer

    68: int 10h

    69: ;Note: in all of these displays, the printed character is the ascii

    70: ;value of the result, not the actual result

    71:

    72: mov ah, 00h ;once again, pause until a key is pressed

    73: int 16h

    74:

    75: mov ax, 4c00h ;move the close program directive to the accumulator

    76: int 21h ;perform interrupt 33

    77: End Start ;the program ends

    ---End Copy on Previous Line---

     

    TASM compilation:

    1) Save the program as "math.asm" in the asm folder

    2) open the command prompt and change to the directory that contains TASM

    3) type in "tasm c:\asm\math.asm" and hit enter

    4) type in "tlink c:\asm\math.obj" and hit enter

     

    Windows FASM

    1) change line 1 to "format MZ"

    2) change line 2 to "stack 200h"

    3) change line 3 to "entry cod:Start"

    4) change line 5 to "segment dat"

    5) change line 9 to "segment cod"

    6) change line 16 to "mov ax, dat"

    8) place square brackets around all references to memory labels not preceeded by "offset"

    7) remove all instances of the word offset

    8) remove line 77

    9) Save the program as "math.asm" in the asm folder

    10) open the command prompt and change to the directory that contains FASM

    11) type in "fasm c:\asm\math.asm c:\asm\math.exe" and hit enter

     

    To run the program in Windows:

    1) type "c:\asm\math" and hit enter

    2) press any key every time the program pauses (4 times)

     

    Linux NASM

    Forthcoming: I finally downloaded NASM for Windows and found that it does not provide a linker to create .exe files, so I'm looking into this before I provide NASM support. Hopefully I will have another hard drive soon so I can install Linux and provide true tested support for all my Linux readers. Unitl then, the commands are still the same.

     

    Program explanation:

    There is not a single command in tis program that we have not covered, and the comments explain what each individual piece of

     

    code does. So I'm not going to repeat all of that. Instead, I'm going to go over the output.

    The first diaplay of a character uses the teletype function. The ascii character for the value of al, in this case 31 which

     

    is the character "1", is displayed onscreen at the current cursor location. Then the cursor is moved aherad one. THis is

     

    why the next display, the question mark, follows the "1". The question mark is also displayed using the teletype function,

     

    al contains 3fh (40h - 01h = 3fh) which is the ascii code for "?". The cursor is once again updated. The next display would

     

    folow the question mark, except we used the display string VGA function. This function takes the location to print text, and

     

    we specified the upper left corner of the screen. We specified the same location for the next display, so this display is

     

    overwritten.

     

    If you exmanie the code, you will find that the value of ax that we stored in Multiply is 5940h, yet the characters that were

     

    displayed can be coded as 4059h. This is because the PC is a little-endian system. What this means is that in multipart

     

    data, the lower part is stored first. (See figure 3) Because of this, if you move ax into data, al is stored before ah is

     

    stored. The computer automatically loads the first part of the data into al and the second part of the data into ah when you

     

    move data into ax. This automatic switch is why data defined in bytes can only be accessed by byte registers, and data

     

    defined in words can only be accessed by word registers. However, the display string VGA interrupt reads straight from

     

    memory without adjusting for how the data was defined. So it displays the lower part before the higher part. (In reality,

     

    this access limitation is a compiler made limitation. Machine code fully allows you to access data stored in words as bytes

     

    or vice versa.)

     

    Figure 3:

     

    Data dw 00h, 00h, 00h, 00h ;the commas separate different pieces of data

    Data: [00][00][00][00][00][00][00][00] (represented in hex)

     

    mov Data, 1234h

    Data: [34][12][00][00][00][00][00][00] (represented in hex)

     

    mov ax, Data

    ax: 1234 (represented in hex)

     

    Review:

    ADD instruction

    SUB instruction

    MUL instruction

    DIV instruction

    INC instruction

    DEC instruction

     

    Coming up next:

    Control structures

    Procedures

    We finally use the stack

     

    Questions? Comments? Something you'd like to see? Let me know and I'll add it in.


  4. The problem with Bubble sort is that it has the potential to take twice as long. If we assume that each step takes up one unit of time, then all of the checks add up and make the time twice as long. I do admit that Bubble sort has the potential to be very fast, and may actually be the best option. I'm still looking for a method with a definite short amount of time. And my method isn't random, it is the same principle as sort spot 1, then spot 2, then spot 3, et.c, except running from both ends at the same time.


  5. Actually, IE has 2, not 1. Since IE used ot be the most popular browser (I don't know if it is anymore or not), there are some javascripts or other scripts or miniapps written for IE compatibility, but no one bothered to check other compatibility, so they don't work in some browsers. For FF versions < 1.0, this was a problem (at least for me). And to make it worse, most of them are on business pages, not personal pages. Stupid business. But since other browsers are fixing this problem, maybe we'll make it worth .5 instead, so IE has 1.5


  6. Admins: I posted this at Xisto as well, but wanted to make sure people here saw it, if I shouldn't have, please delete this.For those of you with Firefox, simply updating to version 1.01 fixes the problem. If you have version 1.0, a red arrow pointing up in a circle should appear on the toolbar towards the right side. If you click it, it will allow you to easily update.


  7. Well, I don't program in Delphi, but the hardest part of making an anti-spyware program is building a list of spyware files. Once you have that done, all that is needed is a search utility to find them on the hard drive, which I doubt is too hard to do in Delphi. If you can't figure it out, I could guide you through an assembly routine that you could place as an include in your Delphi program. But I imagine Delphi has some capability of finding files on its own.


  8. I have absolutely no idea why 1 is pushed onto the FPU stack, we should ask intel. And it's really cool that we are number 1, I've always liked being number 1. But for the hard disk access, since I assume you are still using real mode (you earlier stated that you hadn't dabbled in protected mode), I would simply let the Interrupts take care of it. There is a way, and I haven't needed the hard drive for anything other than opening text files (which it is easiest to use DOS interrupts for), to set up the hard drive with a task and then continue processing until the task is completed, and then finish up with that task using interrupts. If you enter protected mode, I would let the PIC handle it, because the PIC sends an interrupt when the hard drive finishes, so just create an interrupt to handle that. That would be the most efficient for an OS, but the harder method. And I apologize for not placing a tutorial up on Sunday, I have been really busy, so I'm working on it now, and I'm going to post at least one other this week, and, if I have time, a special VGA intro.


  9. There are so many useful languages available right now, it really doesn't matter which language you pick. Almost all of them have the capability to do many similar things, so just choose one to get started. Once you learn one language, switching to another becomes much easier. Plus, the more languages you know, the better. Since your dad probably has lots of reference books for Perl, if he is recommending knowing it, that would probably be a good place for you to start.


  10. However, both Firefox and IE are based off of a Mozilla browser. Firefox is based off of a more recent Mozilla browser than IE is, but they are both based on Mozilla. At least I am assuming that that is why, when doing a browser check with environment variables in CGI that IE shows up as being a Mozilla 4 browser. If I am wrong, please correct me. If I am right, than lazy programmers not wanting to change a GUI that works could account for the similarities between Firefox and IE.


  11. Another thing I like to do is test my site on as many different browsers and platforms as possible. To help with this, I found an interesting tool called Bobby. Unfortuantely, Bobby no longer seems to be free, but it does offer a search embedded into the home page that allows one check per minute. And in case you were wondering, Bobby does not like the Xisto homepage: http://forums.xisto.com/no_longer_exists/=.


  12. I just start it up in notepad from a template file I created which has the basic header, body, and html tags set. I also try to use css scripts that are not a part of the html code itself to allow trhe same css format for many documents. Whenever I am doing a site that has a particular color scheme, I always make a new template just for that site. It also allows me to create sites very quickly.


  13. Okay, you're right about the fact that a 1Mhz computer runs at 10^6 clock cycles per second, and I knew that, so I don't know why I posted the Megabyte number. Second of all, I doln't know why you brought up the Mbps piece of information. But thank you for reminding us of it. Thirdly, this is the forum for assembly and Delphi programming, so the people in here are interested in assembly programming for their various reasons, and I personally feel that no one language is ever superior to any others. So when a person in this forum asks about clock cycles, they are probaby working in assembly and would have to worry about the device level information. If no one worried about device level information, none of the higher level programming would work either. But thank you for obviously reading this thread (which is apparent because you quoted me) and for attempting to fix my mistakes, keep up the good work.


  14. Okay, I'm not looking for code here, just the steps the algorithem would go through. I am trying to find the fastest algorithem to sort a list of elements. So far the fastest I have come up with is as follows (demonstrated on a five element list).Step List Procedure0 dbace this is the starting list1 bdace compare spots 1 and 2, switch if necessary2 bdace compare spots 5 and 4, switch if necessary3 adbce compare spots 1 and 3, switch if necessary4 adbce compare spots 5 and 3, switch if necessary5 adbce compare spots 1 and 4, switch if necessary6 adbce compare spots 5 and 2, switch if necessary7 abdce compare spots 3 and 2, switch if necessary8 abcde compare spots 3 and 4, switch if necessary9 abcde compare spots 3 and 2, switch if necessary (this last step is needed occasionally even though it appears redundant)If you have a faster method or comments on this one, I'd love to see it. The purpose here is to find an algorithem that can be aplied to any language.


  15. Considering that most of the abbreviations that people use are three letters and there are few words that people will actually type into a search engine that are three letters, you could block all words that are three letters or shorter. This is not the best idea because people will want to search for things like "cat" or "dog." You can definitely block words that are two or one letter, because those are only inconsequential words. Yuo can also have a vowel/consonant checker, and if a word contains no vowels, no consonants, three or more vowels in a row, or three or more consonants in a row, block it. I may be able to help more if you explain to me what the purpose of diaplying the top 15 searched for words are, sometimes understanding the reasoning leads to interesting solutions.

×
×
  • Create New...

Important Information

Terms of Use | Privacy Policy | Guidelines | We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.