请把这个代码加入精华区--用汇编实现的linkedlist.
skumria:x86 dynamic singly linked
04.18.2003 at 04:21AM PDT, ID: 8353500
skumria:x86 dynamic singly linked
04.19.2003 at 08:23PM PDT, ID: 8361493
TrueIdiot:x86... Well, I don't know that processor all that well, and I definitly don't know the instruction set, but here goes (note: this will create a node with one byte of data storage):
start_of_user_ram equ xxxxh ;defines the start of user mem (this isn't the real number, you need to find that bit out on your own)
add_node:
ld hl,free_ram
ld de,start_of_user_ram
add hl,de ;the next free byte
ld (hl),a ;you stored the value you wanted to add in a before you called the function, right?
inc hl
ld free_ram,hl ;the newest free byte
ld de,node_count
inc de
ld node_count,de ;we've added a node
ret ;return to caller
edit_node:
ld hl,start_of_user_ram
add hl,de ;the # of the node you wanted to edit is in de (sorry, no names)
ld (hl),a ;the new value
ret
read_node:
ld hl,start_of_user_ram
add hl,de ;see edit_node for explaination
ld a,(hl) ;the value of the node now in a
ret
delete_node: ;now things get tricky
ld hl,start_of_user_ram
add hl,de ;this should look familiar by now
inc hl ;the next node
ld bc,node_count
sub bc,de ;how many nodes after the one we want to delete
mem_move_loop:
ld d,(hl) ;gets a byte
dec hl
ld (hl),d ;moves it up one byte
dec bc ;checks to see if we'e moved all the nodes
jp nz,mem_move_loop ;if we haven't, do it again
ld de,node_count
dec de
ld node_count,de ;we've removed a node
ret
free_ram: ;just a static variable
.db 0000h
node_count:
.db 0
.end ;the end of the file
There you have it. a linked list in asm. If you don't understand it, or need something else, post a comment. Also, I'll work on an algorithm explaination later. Like, in the morning.
p.s. What kind of a value do you want to store in this fine list?
p.p.s. post a comment if you need help understanding the syntax. this is for the z80 processor using the TASM assembler, if you want to look it up yourself
p.p.p.s. you might want to start the equate for the start_of_user_ram a little farther in into memory than the actual start, because this will obliterate anything a new node creates itself over. It really should be called start_of_list,not ram.
04.20.2003 at 06:10PM PDT, ID: 8364320
TrueIdiot:Well, as promised, the algorithm explaination:
The list is in RAM. This you know. I am assuming that you know how to create a linked list in a high level language. The reason why you need pointers in C++ or Java or whatever you use, is b/c the compiler puts the nodes at "random" places in memory. The main difference is that, in assembly, you have no real choice but to manually assign memory to certain tasks. Therefore if memory is allocated in a planned-out way, you'll always know where to look for something. If that wasn't clear enough, here's some pictures:
Ram is organized like this:
|-----|
|0001h|
|-----|
|0002h|
|-----|
|.....|
|-----|
|.....|
|-----|
|fffeh|
|-----|
|ffffh|
|-----|
where each "block" is equal to one byte. So, why not just store you list in a straight segment?
|-------|
| start | ;what you equated, remember?
|-------|
|myList0|
|-------|
|myList1|
|-------|
|myList2|
|-------|
|.......|
|-------|
so, to access myList[?]:
myList[1]=start+1
myList[454]=start+454
myList[n]=start+n
that's what the (hl) operator means. Look at adress hl in memory.
Now, deleting:
since we traverse the list by knowing the size of the blocks of data, if one block is empty, we get all thrown off. The simplest way to remedy this is to move the data when a node is deleted.
Our List:
|-------|
| start |
|-------|
|myList0|
|-------|
|myList1|
|-------|
|myList2|
|-------|
|.......|
|-------|
We want to delete myList1:
|-------|
| start |
|-------|
|myList0|
|-------|
|xxxxxxx|
|-------|
|myList2|
|-------|
|.......|
|-------|
so we then move all the others up: (note: for claracy, the items have all retained their index. the point is the value they contain has been moved, there is not a gap in the list)
|-------|
| start |
|-------|
|myList0|
|-------|
|myList2|
|-------|
|myList3|
|-------|
|.......|
|-------|
and there you have it. If you have any questions, please post a comment. Also, all I have really learned about z80 to x86 sytax is:
ld = mov