I need beginner advice...

All about the OSDev Wiki. Discussions about the organization and general structure of articles and how to use the wiki. Request changes here if you don't know how to use the wiki.
Post Reply
User avatar
LadyTemoshi
Posts: 7
Joined: Tue Aug 13, 2013 4:52 pm

I need beginner advice...

Post by LadyTemoshi »

Hi, I'm too tired today because I was up until midnight last night using Google to find stuff. I started researching only 2 days ago, and I got some starter things already, such as registers and 16, 8, 4, 2, and 1 byte loaders, but I still need beginner stuff to read.

I learned MIPS Assembly, but only basic programming stuff. I know how SP works and registers HI and LO with the division call, plus some other basic commands. I just need to learn how to program in x64 Assembly because I want to start working on a project, and I need to know where to start.

Beginner tutorials would be bloody fantastic, give me whatever helps. I'm all eyes, ears, nose, mouth, and brains.

I'm going to lay down for a bit now. Thanks.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: I need beginner advice...

Post by AJ »

Hi,

See the Wiki Main Page, particularly the introduction and barebonse tutorials. For a thorough grounding in x86 assembly, you may be better off starting with a formal text on assembly language (I have often heard The Art of Assembly recommended, but don't know how up to date that information is). Of course, you'll also want the Intel Software Developers Manuals.

Cheers,
Adam
Craze Frog
Member
Member
Posts: 368
Joined: Sun Sep 23, 2007 4:52 am

Re: I need beginner advice...

Post by Craze Frog »

You definetely want a set of documents called
"Intel® 64 and IA-32 Architectures
Software Developer’s Manual"


I downloaded these from intel.com. They list all instructions and other specifications of the platform. I do not recommend The Art of Assembly.
h0bby1
Member
Member
Posts: 240
Joined: Wed Aug 21, 2013 7:08 am

Re: I need beginner advice...

Post by h0bby1 »

the big problem with intel assembler is that intel architecture is very old, and intel processor can function in many different way, regarding how memory is addressed, regarding 16/32/64 bit code, and for optimisation there is also the whole thing of pipelining who can execute certain instruction in parallele, cache mannagment , if you plan on making an os, you'd rather being familliar with all those different modes, i don't know a lot about 64 bit, but it work in a similar way than 32 bits

basically you have two type of register, working registers, and address registers, plus flags that are set after some instruction to test the result, address register are separated from segments registers and ofset register, they work differently depending on which memory model the intel is running

originally in 16 bit real mode, you only had 16 bit registers, you made a 32 bit address by combining the 16 bits segment and ofset register who work as pairs, the 3 main pairs of address registers are

es:di
ds:si
ss:sp/bp

es,ds and ss are the segment register, di, si and sp are the ofset registers, when you do an instruction to move data to or from memory, it will use one of those register, the function of ds:si and es:di are similar, with some instruction es:di is traditionally used as write target and ds:si as reading, like with the instruction movsb, it will read bytes from es:di and write them in ds:si, ss:sp is the stack pointer , they are all 16 bits registers

depending in which mode you are, the address made by those pair of address register will change, in 16 bit real mode, which is the mode in which the intel start at boot time, the physical address is computed using segment*16+ofset, allowing about 1Mo to be addressed, if you access a memory address using only the ofset register like mov ax,[si], it will assume the segment to be the other of the pair, in the case ds for si, es for di, ss for sp/bp, any memory instruction will use ds as the segment if not otherwise specified, if you use one of the ofset register as the address, the corresponding segment register is used

in 32 bit mode, the ofset register are made 32 bits, but it's not a big use in real mode because segment register are still 16 bits, in the segment mode, you then add some entry in the global memory table to define a memory zone with an id, and setting the segment register to this id make the address instruction from the 32 bit ofset register being the start of the segment entry in the global memory table + the ofset

the working register for 32 bits are eax,ebx,edx,ecx, for 16 bits ax,bx,cx,dx , the 16 bits register map to the lower 16 bit part of the 32 bit register, the 16 bits register are split into two 8 bit registers, for ax it al (low 8 bits) and ah (high 8 bits), dx dh/dl, bx bh/bl, cx ch/cl, the 64 bits register are same with a r prefix

then you get as well the simd instruction like mmx and sse, who are register who contain several value packed in a single register, a 64 bit mmx register can either handle 8 bytes, 4 words, 2 dword, and operation done on those register execute the operation on all the value in parallele in sort that you can have 8 addition 8 bits done in a single instruction, sse works the same with float vector, an sse register is 128 bit and made of 4 float of 32 bits, and operation done on the register like addition will be made on the 4 float at the same time

fpu operation are a whole other thing, they use their own set of register and instruction, it's actually a coprocessor and first intel didn't even have fpu, and the registers used with fpu overlap with the mmx registers, so you can use both at the same time, if you use mmx, then you need to call emms to restore the fpu registers, and screw up the mmx registers

the fpu works with a stack, you load a float in the stack with fld , and then operation are done on the stack, if you load some value into the stack and use mmx instruction, those value will be screwed, and same if you use fpu instruction it will screw up mmx registers

comparison are mostly done using the cpu flags, they are like state that can be tested with conditional jump instruction, you can chek intel manual to see which instruction modify which flag and which conditional jump can take it into account, fpu comparisons are specially tricky for that, they use the flags in a weird way if you need conditional jump from fpu comparison

nowday if you target pentium > 3 who support sse instruction set, you can safely drop the fpu thing, cause sse instruction are much faster and much more convenient to use, and can work in conjunction with mmx instruction, mmx is avaible since the last version of pentium 1, so you can expect it to be avaible on all plateform nowdays

then the stack i guess it's pretty much standard, it's the pair ss:sp, instruction push decrease (e)sp and store the value at the address ss:(e)sp, pop copy back the value at the top of the stack and increment stack pointer (e)sp, you can access the stack directly without using push/pop by manipulating the stack pointer manually with add/sub on esp and then doing regular memory access on ss:esp

intel can also handle a memory mode with pagination, and multi tasking, interuptions are handled by a separate controller than need to be programmed separatly, you can just enable/disable them using cli/sti to clear and enable interuption handling

for pipelining, also need to check intel manual, it can provide significant speed optimisation if you can arrange the instruction order for that instruction can be executed in the two pipeline at the same time

if you plan on size optimisation, it can be worthy to look at the different opcodes, and how intel instruction can be assembled into different opcode depending on the operand size, a jump to a 8 or 16 bit relative address is smaller than a jump to a 32 bit address, same for most instruction, mov eax, 0 is much bigger than mov ax,0 because the opcode is for 32 bit instruction are one byte bigger, and the immediate value is made 32 bit, some instruction can also have optimized opcode, like moving ax to memory has special opcode that is one byte less than moving other registers, it can worth a look if you want to optimize assembler for size
Post Reply