October 31st, 2003, 11:15 PM

Questions in Asembly Langugae:(
some problems that i don't understand~ I hope you know this stuff=)
1) Memory Location has physical address at 4A37bh. Compute
a) offset address if segmetnt number is 40FFh
b) segment number if offset address is 123bh.
2) Suppose that the following data are loaded starting at offset 000h:
A DB 7
B DW 1ABCh
C DB Hello
Give offset address assigend to varaible a, B, C
Give contents of the byte at offset 002h in hex
Give contents of the byte at offset 0004h in hex
Give the offset address of character in Hello
(note: this problem has been done 3 times but i still don't understand it:()
(The next problem , i know the answers too, btu i don't understand for half of the problems, of how the solutio ncame to be...)
3) tell whether each of the following instructions is legal or illegal W 1& W2 are word variables and B1 & B2, byte varabiles
a) Mov, Ds, Ax
b) Mov, Ds, 1000h
c) Mov Cs, Es
d)Mov W1, DS
e) XChg W1, W2
f) Sub 5, B1
g) Add, B1, B2
h) Add Al, 256
i) Mov W1, BL
and the last subject havign trouble to understand is...
Translation of HighLevel Languge to Asssembly language
Statement Translation
B=A Mov Ax, A; Move a into Ax
Mov B, Ax; and then into B
A=5A Mov Ax, 5; put 5 in AX
Sub Ax, A; Put Ax contains 5A
Mov A, Ax, put it into A
NEG A; A=A
ADD A, 5; A=5A
A=B2*A Mov Ax, b; Ax has B
Sub Ax, A; Ax has BA
Sub Ax, A; Ax bas B2*A
Mov A, Ax; move result to A
(These are examples in the book, but i don't undertsand them.*sigh* i study the whole day and i am going crazy! I have an exam on monday and so hopefully, you all can help me~ thanks ofor yoru tim as always..=)
November 1st, 2003, 11:21 AM

Heh, I haven't programmed in Assembler in a long time and 8086 assembler in a very long time, but I'll give it a shot. The first question is obviously for the 16 bit 8086 (and compatible chips) because of the segment:offset architecture they had.
1. The 8088 and 8086 (and succeeding chips for "backward compatibility") had a 20 bit address register, but only a 16 bit address bus (8088 had an 8 bit bus), so they had to figure out how to specify 20 bit addresses with 16 bit registers. Enter the segmented memory architecture. Basically, the idea was to specify the addresss as two 16 bit numbers, a segment and an offset. Internally, the chip would shift the segment left by 4 binary digits (i.e. 1 hex digit) and then add the offset to it, to get the absolute address. To put it another way, think of the segment as page number within a book and offset as the word number within that page. So instead of specifying a large word number from the beginning of the book, you could specify a smaller page number and a smaller word number and compute the larger word number from these two smaller numbers. So, let's say you had:
Segment: A000
Offset: 1234
So first shift the segment left by one hex digit (or 4 binary digits), therefore we get A0000. Now add offset to it, we get A1234, which is the absolute address. Seems, simple enough eh... not so fast. You could also refer to the same address (A1234) like this:
Segment: A100, Offset: 0234
Segment: A110, Offset: 0134
Segment: A123: Offset: 0004
and so on. Thus, you have many ways to refer to the same absolute memory address using different values of segment and offset. So now, on to your question 1.
Memory address is 4A37B in hex.
(a) Segment # is 40FF, so shift left by 1 hex digit and we have 40FF0. Therefore to compute the offset, we compute 4A37B  40FF0. So dig out a hex calculator (Windows calculator has a scientific mode View >Scientific) and compute this. We get the offset as 938B
(b) Offset is 123B, and address  offset is 4A37B  123B = 49140. Therefore segment is 4914
2. DB is to Data Bytes and DW = Data Word (i.e. 2 bytes) in 8088 assembler notation. So starting from 0000, let's write down the offsets of each data.
A is declared as DB 7, which means one byte containing '7' in it
B is declared as DW, which implies 2 bytes. The 1ABC is the contents of B in hex.
C is declared as DB Hello, which means 5 bytes containing 'H', 'e', 'l', 'l', 'o'.
So A starts from 0000 and takes up one byte, so it occupies offset 0000. Now B starts from the end of A, so it starts from 0001. Also B is two bytes long, so it takes up offset 0001 and 0002. Now C is 5 bytes long and starts at the end of B, so it starts ad address 0003. Also C is 5 bytes long, so it uses up 0003, 0004, 0005, 0006, 0007. Let's write this as a table  remember 2 hex digits = one byte.
Code:
Offset Content Notes
0000 07 Content of A
0001 BC Part content of B
0002 1A Part content of B
0003 48 ASCII value of 'H' in hex
0004 65 ASCII value of 'e' in hex
0005 6C ASCII value of 'l' in hex
0006 6C ASCII value of 'l' in hex
0007 6F ASCII value of 'o' in hex
So after that, figuring out what is in which address is a piece of cake.
Up the Irons
What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
"Death Before Dishonour, my Friends!!"  Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
Down with Sharon Osbourne
"I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website."  Nilpo
November 1st, 2003, 12:11 PM

One has to ask why? Who still uses 16bit x86 realmode?
Good answer Scorpions4ever. Small irellevant point: 8086/8088 both have a 20bit address bus (1Mb addressable), but only 16 bit registers. The 8088 has an 8 bit data bus, wheras the 8086 had a 16bit data bus.
Clifford.
November 1st, 2003, 12:18 PM

hm.question...can you explain to me the Translation of High Level Assembly language.~
I am trying to understand the concept!
November 1st, 2003, 11:30 PM

find this helpful?
Code:
#define USING_ASM
int x = 0; //i cant figure out how to refer to a local variable in asm
//if you know how then tell me. 'man gcc' has incorrect info.
int main(void)
{
#ifndef USING_ASM
x = getpid();
#else
//first we need to call the getpid function
//then we need to put it's return value into x,
//the return value of a function is always in the eax register,
//the system call number for getpid is 20,
//the interrupt handler we need is 0x80, so
asm("movl $20, %eax");
asm("int $0x80");
asm("movl %eax, (x)");
#endif
#ifndef USING_ASM
return(x % 2); //returns 0 if pid is divisible by 2, 1 if not
#else
//we need to divide x by 2 and test the remainder against 0
//to divide, EDX:EAX is 64 bit number being divided;
//quotient gets put in eax, remainder edx, then we test edx against 0
//if the remainder is 0, we return 0, else we return 1
//
//eax already has the value of X in it, so just extend it to edx
asm("cdq"); //make double word a quad word(sign extend eax to edx)
asm("movl $2, %ecx");
asm("div %ecx");
asm("movl %edx, %eax"); //edx has the correct return value in it
return; //eax has the return value as usual
#endif
}
Last edited by infamous41md; November 1st, 2003 at 11:32 PM.
November 2nd, 2003, 07:22 PM
