Jump to content

  • Log In with Google      Sign In   
  • Create Account

Calling all IT Pros from Canada and Australia.. we need your help! Support our site by taking a quick sponsored surveyand win a chance at a $50 Amazon gift card. Click here to get started!


NUCLEAR RABBIT

Member Since 12 Apr 2006
Offline Last Active Mar 04 2015 09:34 PM

#5209294 MASM Assembly Help!

Posted by NUCLEAR RABBIT on 07 February 2015 - 12:26 PM

 

Another thing, I've been kind of thinking of the int 21h call as a 'do it' operation. Is this the right way to think about the "int 21h" call? I tried googling int 21h to find a clear explination of that operation, but had no luck :/ If so, how does the "int 21h" call know which lines I want it to "do"?


INT is sort of like a CALL instruction that does some extra stuff. Kind of like how CALL is just a JMP that does extra stuff.

Somewhere in memory, there is an "interrupt vector table" (IVT for short) which is just an array of function pointers. The INT instruction looks up an entry in that table (using the numeric operand you gave to INT as the index) and then uses the address in the array to call a function.

Back when I used DOS in real mode, the IVT was at memory address zero.

"But who creates the IVT", you ask? The BIOS does, at system startup. You can read more about the gory details here:

http://wiki.osdev.org/System_Initialization_(x86)


After INT has found the address and called the function, the function itself works just like what Buckeye posted.

 

 

Sweet, thank you for the explination and link! gonna read that in a few mins biggrin.png

 

 

Looks like most of the important bits were covered, but there are some loose ends.

The first and very important bit is that all of those commands are dead or dying. While Ralph Brown's Interrupt List is useful for hardware developers and for developers in the 1980s and 1990s, today in 2015 it is mostly historical.


That said, if you are doing DOS based programming, that old masm assembler can be a fun way to learn lower level programming. You'll probably need a DOS emulator like dosbox if you want to have most of the old functionality, but I'll assume you've got all that.


Interrupt 21h is the DOS general functionality interrupt.

Hundreds of pieces of DOS functionality were tied into that interrupt. Exactly what functionality took place depends on the contents of the AH register.

For example:
01h reads a byte from standard input
02h writes a byte to standard output
09h writes a string to standard output (as you discovered)
2Ah reads the system date
2Bh sets the system date
2Ch reads the system time
2Dh sets the system time
39h creates a disk directory
3Ah deletes a disk directory
3Ch creates a file
3Dh opens a file
3Eh closes a file

And on and on.

There are/were interrupts for every piece of functionality provided by the OS and the hardware. Graphics hardware was generally accessed through interrupt 10h and various ports and memory blocks. The mouse was generally accessed through interrupt 33h.

One of my favorite little bad hacks was to open edlin (a very simple line editor) jump to position 100 (where command executables start) and enter the two bytes cd19. Then save it as a .com file. CD is the bytecode for 'interrupt', I'll let you look up interrupt 19h. Then I'd call the command in their autoexec.bat file, before any TSRs were loaded. Fun times were had by many, but not all.

Anyway, back on track.

Almost every interrupt will expect some values loaded into registers. The system would document those. Back in the 1980s many computers came with manuals that documented all or most of the overriden interrupts and their parameters. Devices like printers and modems would also include details of their command codes and escape sequences. It was cryptic to most people, but necessary for developers and system administrators in order to customize the software and hardware to run together.

You as the programmer could then look up the functionality you needed. If you wanted to change the graphics mode you would set the right parameters to indicate the graphics mode, then call interrupt 10h, and when it returned it would load the status codes. If you wanted to read the mouse coordinates you would set the right parameters to indicate what you wanted to read, and when it returned it would load the mouse position.


As others have pointed out, this is rather dated. Most of these are virtualized on modern hardware, you have your own little sandbox you are playing in and a private little interrupt table is established for your application. Many of the old 16-bit function DOS calls no longer work as Microsoft declared years ago "DOS is dead." But in practice it is not as dead as they had hoped.

 

Awesome explination and thanks for a short desc of some other interrupt calls, I think I am begining to understand things better! About your cd19 and autoexec.bat hack, did that allow you to control their ROM utilities? haha I looked it up and I read a little about the bootstrap loader.

 

About this being 16 bit DOS and to learn 32 bit instead, I wish I could because it sounds like its more useful in this day and age, but the reason I am learning it is because it's a required class I need to go toward my CS degree. However my instructor said this semester might be the last semester he teaches this course. All we have done is a "Hello World" application so far, so I am just trying to learn some stuff on my own.

 

Once again I want to thank everyone for your explinations and help! cool.png




#5209181 MASM Assembly Help!

Posted by NUCLEAR RABBIT on 06 February 2015 - 06:35 PM

Hello,

 

So I am currently learning MASM 8086 Assembly right now I am have trouble with an application I am attempting to mess around with and create for practice. Not sure what the errors I am getting mean (I am extremely new to assembly). Can someone please help me understand what I am doing wrong? I have attached the screenshot of the error messages and the source code. ANY help would be greatly appreciated!

 

age.asm

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                              ;
;   Name: Brandon                              ;
;   Date: 2/6/2015                             ;
;   Desc: Simply asks the user for their age   ;
;         and then greets the user with the    ;
;         age value they entered in            ;
;                                              ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

.model small
.stack 100h

.data
age db ?
welcome_greet db 'Welcome to the GREATEST application EVER!!!', 10, 13, '$'
age_prompt db 'Please enter your age: ', 10, 13, '$'
result_prompt db 'The age you entered is: ', 10, 13, '$'
exit_prompt db 'Goodbye, hope you enjoyed this AMAZING application!', 10, 13, '$'

.code
main proc
mov AX, @DATA              ; must do everytime
mov DS, AX                 ; must also do everytime as well

lea DX, welcome_greet      ; loads the welcome_greet into the DX registery
mov AH, 9h                 ; DOS command to print a string
int 21h

lea DX, age_prompt
move AH, 9h
int 21h

move AH, 1h                ; 1h is a DOS command to read in a char
int 21h
sub AL, '0'                ; converts to an integar
move AGE, AL               ; saves the value into AGE

move AH, 9h
lea DX, result_prompt
int 21h

move AH, 2h                ; prints a char
int 21h

move AH, 04ch              ; exits the DOS application
int 21h

main endp
end main

Also, I have a few questions about the code I have. Is the DX registery only used for loading output messages into?

lea DX, welcome_greet      ; loads the welcome_greet into the DX registery
mov AH, 9h                 ; DOS command to print a string
int 21h

Like I said, I am extreme beginner to assembly so any explinations/corrections would be awesome! biggrin.png

Attached Thumbnails

  • Screen Shot 2015-02-06 at 4.23.18 PM.png



#5185612 Polymorphism and Interfaces in Java

Posted by NUCLEAR RABBIT on 07 October 2014 - 02:23 PM

Hello,

 

So I recently learned about Interfaces and thought I had a good grasp, but I'm not sure why this example does what it does. It creates an interface object and assign it to an ArrayQueue<T>() object. Why not just write it as an ArrayQueue object to begin with, is there an advantage? I think my question relates more to polymorphism maybe, but I also thought that interfaces aren't objects that are initialized, just implemented from in another class.

 

Can anyone help clear the air? I would really appreciate any help! huh.png

Attached Thumbnails

  • Screen Shot 2014-10-07 at 1.15.22 PM.png



#5155138 Writing/Reading from files help needed! (C Programming)

Posted by NUCLEAR RABBIT on 21 May 2014 - 05:13 PM

hello, I am trying to write a program that makes 10 empty entries in my file, updating the first 3, and then asking the user which one to erase back to a blank entry, and then reprints the file contents again with the entry deleted. It seems to work okay ONLY if you delete the first entry, if you try to delete the 2nd or 3rd, the output goes all crazy! Any help would be greatly appreciated! :(

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

typedef struct person {
    char first_name[15];
    char last_name[15];
    char age[4];
    int accNum;
} Person;

int main(int argc, char * argv[])
{
    FILE * file = fopen("/Users/MYNAME/Desktop/person.txt", "r+");
    
    Person blankEntry = {"No First Name", "No Last Name", "0", 0};
    Person person1 = blankEntry;
    
    printf("Records:\n");
    for(int i = 1; i <= 10; i++) {
        fwrite(blankEntry.first_name, 1, sizeof(blankEntry.first_name), file);
        fwrite(blankEntry.last_name, 1, sizeof(blankEntry.last_name), file);
        fwrite(blankEntry.age, 1, sizeof(blankEntry.age), file);
        fprintf(file, "%d", i);
        
        printf("%d. %s\t\t\t%10s%10s\n", i, blankEntry.first_name, blankEntry.last_name, blankEntry.age);
    }
    
    printf("\n\nUpdating Record:\n");
    fseek(file, SEEK_SET, 0);
    for(int i = 1; i <= 3; i++) {
        printf("Enter in first name, last name, and age: ");
        scanf("%s %s %s", person1.first_name, person1.last_name, person1.age);
        
        fwrite(person1.first_name, 1, sizeof(person1.first_name), file);
        fwrite(person1.last_name, 1, sizeof(person1.last_name), file);
        fwrite(person1.age, 1, sizeof(person1.age), file);
        fprintf(file, "%d", i);
    }
    
    printf("\n\nRecords:\n");
    printf("First Name:\t\tLast Name:\t\tAge:\n");
    fseek(file, SEEK_SET, 0);
    for(int i = 1; i <= 10; i++) {
        fread(person1.first_name, 1, sizeof(person1.first_name), file);
        fread(person1.last_name, 1, sizeof(person1.last_name), file);
        fread(person1.age, 1, sizeof(person1.age), file);
        fscanf(file, "%d", &person1.accNum);
        
        printf("%i. %s\t\t%10s%10s\n", person1.accNum, person1.first_name, person1.last_name, person1.age);
    }
    
    int deleteKey;
    printf("\n\nEnter in account number to delete: ");
    scanf("%i", &deleteKey);
    
    fseek(file, (deleteKey - 1) * sizeof(struct person), SEEK_SET);
    fwrite(person1.first_name, 1, sizeof(person1.first_name), file);
    fwrite(person1.last_name, 1, sizeof(person1.last_name), file);
    fwrite(person1.age, 1, sizeof(person1.age), file);
    //fwrite(&blankEntry, sizeof(struct person), 1, file);
    
    printf("\n\nRecords:\n");
    printf("First Name:\t\tLast Name:\t\tAge:\n");
    fseek(file, SEEK_SET, 0);
    for(int i = 1; i <= 10; i++) {
        fread(person1.first_name, 1, sizeof(person1.first_name), file);
        fread(person1.last_name, 1, sizeof(person1.last_name), file);
        fread(person1.age, 1, sizeof(person1.age), file);
        fscanf(file, "%d", &person1.accNum);
        
        printf("%i. %s\t\t%10s%10s\n", person1.accNum, person1.first_name, person1.last_name, person1.age);
    }
    
    fclose(file);
    
    return 0;
}



#5135991 Recursion in C Programming: Confusion Begins

Posted by NUCLEAR RABBIT on 02 March 2014 - 09:55 PM

Hello, 

 

So I was working on a HW assignment in my C programming class, and we are learning about recursion. I guess the idea itself is pretty self explanatory, a function calling itself, but how it works is where I get lost! I got the assignment to work, but I'm not sure why what I coded worked. How does the function know what to return when there's 2 numbers inputted? It's just a function with 2 parameters and no variable changing so how does x and y get altered? I understood my previous assignment where we used recursion to return x to the nth power, but this one is a little less concrete with me.

 

Could anyone help me understand this a little more? Any help is greatly appreciated!

#include <stdio.h>

int gcd(int x, int y)
{
    // base case
    if(y == 0)
        return x;
    return gcd(y, x % y);
}

int main(int argc, const char * argv[])
{
    int x = 54;
    int y = 24;
    
    printf("GCD of %i and %i is %i\n", x, y, gcd(x,y));
    
    return 0;
}



#5132213 Struct Inheritance in C

Posted by NUCLEAR RABBIT on 17 February 2014 - 09:12 PM

The idea is that you'll be able to access and use a Manager as an Employee when you want to treat them as just another employee. For example, if you just wanted to do payroll, you don't care who's a manager or what their title is.

 

So you can create a function, for example, that takes an employee by pointer and prints out the payroll check, and you can pass it pointers to regular employees or pointers to managers by casting them as pointers to employees. The one function will handle both -- If you continue to access a Manager's Employee attributes through the Super member variable as you're doing in your code, then you'd need to separate functions.

 

You'd be doing functionally the same thing by passing the address of a manager's 'super' member variable -- but because its the first struct element, simply casting the Manager pointer to an Employee pointer achieves the same thing. All it says is "Treat this manager as a regular employee."

 

You're awesome!




#5132211 Struct Inheritance in C

Posted by NUCLEAR RABBIT on 17 February 2014 - 09:05 PM

What you have done is called "composition", not "inheritance". The good news is that composition is the right tool to use more often than inheritance.

The pointer cast is what makes inheritance look like inheritance: Some other part of the code can take a pointer to an Employee and do something with it, and if instead of giving it a pointer to an Employee you give it a pointer to a Manager (after casting), it would work just fine.

However, the main reason to use inheritance is not to build neat little hierarchies the way most OOP texts seem to suggest: The main reason is polymorphism, which means you can call a function that takes a pointer to Employee as an argument, and it might do something different depending on the specific type of employee that was passed. In C you would achieve this by making `Employee' have a function pointer as part of its data, so each derived type can provide an appropriate function to call there. (The mechanism that C++ uses is not exactly this; C++ compilers typically use a vtable instead (look it up).)

 

Sweet, thank you! Makes more sense now. And I'll will look into vtables 




#5132207 Struct Inheritance in C

Posted by NUCLEAR RABBIT on 17 February 2014 - 08:50 PM

Hello,

 

I am trying to make a struct type and make another struct built on top of the other struct and I got it working, but I'm not sure what the tutorial means when it says I need to do pointer casting. I know how, but not sure why I have to do this? I seem to have it going without the casting so I'm not sure why they mentioned it. Can anyone help me understand why? rolleyes.gif

 

my code:

#include <stdio.h>
#include <string.h>

typedef struct {
    float wage;
    char name[15];
} Employee;

typedef struct{
    Employee super;
    char title[15];
} Manager;

int main(int argc, const char * argv[])
{
    Manager manager1;
    strcpy(manager1.super.name, "Steve");
    strcpy(manager1.title, "Manager On Duty");
    
    Manager manager2;
    strcpy(manager2.super.name, "Jack");
    strcpy(manager2.title, "CEO");
    
    printf("Title:\t\t\t\tEmployee Name:\n%s\t\t%s\n", manager1.title, manager1.super.name);
    printf("%s\t\t\t\t\t%s\n", manager2.title, manager2.super.name);
    
    return 0;
}

tutorial code: (not same example)

typedef struct
{
    // base members

} Base;

typedef struct
{
    Base base;

    // derived members

} Derived;

then they say "As Derived starts with a copy of Base, you can do this:"

Base *b = (Base *b)d;

"Where d is an instance of Derived. So they are kind of polymorphic. But having virtual methods is another challenge - to do that, you'd need to have the equivalent of a vtable pointer in Base, containing function pointers to functions that accept Base as their first argument (which you could name this)"




#5128620 C If Statement Question

Posted by NUCLEAR RABBIT on 03 February 2014 - 09:58 PM

Hello! 

 

I am taking a C programming class and my teacher uses the "puts statement" to combine an if statements with the action if the condition is met. I saw too different examples of doing the same thing and was just wondering which method is more "standardized" and which method is not recommended using? It's nothing too serious, but it got me curious. thanks! 

 

PS - here's an example:

#include <stdio.h>

int main(int argc, const char * argv[])
{
    int grade;
    
    // gets user input
    printf("What is the students grade? ");
    scanf("%d", &grade);
    
    // alerts user if passed or failed
    (grade >= 60) ? printf("Passed!\n") : printf("Uh-ohhh...\n");
    // puts statement version
    puts(grade >= 60 ? "Passed!\n" : "Uh-ohhh...\n");
    
    // displays grade
    if(grade >= 90)
        printf("Grade = A\n");
    else if(grade >= 80)
        printf("Grade = B\n");
    else if(grade >= 70)
        printf("Grade  = C\n");
    else if(grade >= 60)
        printf("Grade = D\n");
    else
        printf("Student failed.\n");
    
    return 0;
}



PARTNERS