Author Topic: about segment  (Read 23181 times)

nobody

  • Guest
about segment
« on: January 10, 2009, 02:36:49 PM »
hi, there
today, I use nasm write a dos programme, nasm + (ms)link5.0
but there is something wrong, example is here:

Code: [Select]
[bits 16]
segment data
BUF: db 45, 61, 70, 86, 75, 100, 69, 88, 81
n equ $ - BUF

RESULT: resb 2


[bits 16]
segment stack
st resb 100


[bits 16]
segment code
..start:
mov ax, stack
mov ss, ax
mov sp, 100

mov ax, data
mov ds, ax
mov cx, n
mov si, BUF
mov di, RESULT

mov ah, 0
mov bh, 0

.0:
mov al, [si]
cmp al, 60
jb .1

inc ah
jmp .2

.1:
inc bh

.2:
inc si
dec cx
cmp cx, 0
jz .exit
jnz .0

mov [di], ah
mov [di+1], bh

.exit:
mov ax, 0x4c00
int 0x21

simple, but when i use debug.exe run it, result is here

Code: [Select]
-r
AX=0000  BX=0000  CX=00AA  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=14A1  ES=14A1  SS=14B1  CS=14B7  IP=000F   NV UP EI PL NZ NA PO NC
14B7:000F B8B114        MOV     AX,14B1
-t

AX=14B1  BX=0000  CX=00AA  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=14A1  ES=14A1  SS=14B1  CS=14B7  IP=0012   NV UP EI PL NZ NA PO NC
14B7:0012 8ED0          MOV     SS,AX
-t

AX=14B1  BX=0000  CX=00AA  DX=0000  SP=0064  BP=0000  SI=0000  DI=0000
DS=14A1  ES=14A1  SS=14B1  CS=14B7  IP=0017   NV UP EI PL NZ NA PO NC
14B7:0017 B8B114        MOV     AX,14B1
-t

AX=14B1  BX=0000  CX=00AA  DX=0000  SP=0064  BP=0000  SI=0000  DI=0000
DS=14A1  ES=14A1  SS=14B1  CS=14B7  IP=001A   NV UP EI PL NZ NA PO NC
14B7:001A 8ED8          MOV     DS,AX

ds equal es
but as we know
code is :

Code: [Select]
       mov ax, stack
  mov ss, ax
mov sp, 100
mov ax, data

what's wrong ??
welcome to talk to me.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: about segment
« Reply #1 on: January 11, 2009, 03:50:19 AM »
Wrong? Not tested, but it looks right to me. Are you bothered by the fact that DEBUG doesn't show the "mov sp, 100"? That's easily explained. After a mov to ss, interrupts are disabled for the next instruction, so DEBUG executes the next instruction (the "single step" is accomplished by replacing the next instruction - temporarily - with an interrupt). Notice that sp *is* 100 (64h) when DEBUG stops.

[some buggy CPUs *didn't* disable interrupts after a mov to ss, so you'll sometimes see:

Code: [Select]
cli
mov ss, ???
mov sp, ???
sti

I'm pretty sure these "buggy CPUs" are all dead these days, but "just to be safe", we should probably still do that???]

Well... strictly speaking... "segment stack" doesn't give you a "proper" stack. The first "parameter" to "segment" is just a name - "stack" is good, but it could be anything. We really should have a second "stack" in there - this sets the "type"(?) of segment:

Code: [Select]
segment stack stack
resb 100

With this small change, dos will load your program with ss:sp properly set, and the:

Code: [Select]
mov ax, stack
mov ss, ax
mov sp, 100

is unnecessary. I don't know why the example in the manual shows it that way. Try it with the repetitive "segment stack stack" and observe the startup values in ss:sp. I think this is "better"...

You mention "ds equal es". This is true before the "mov ax, ds" - ds = es = PSP (Program Segment Prefix) on startup. But this is not the same as your data segment! After the "mov ds, ax", es will still be PSP, but ds will be your data segment. Your program doesn't use es, so this is okay. You might want to add "mov es, ax", so es = data too... in case you *do* use es...

The "[bits 16]" is okay - Nasm defaults to 16 bits in "-f obj" anyway. If you wanted 32-bit code, "[bits 32]" would *not* be enough to do it, though. You'd need "use32" in the segment declarations... ("[bits 32]" wouldn't hurt, but it's the "use32" that does the trick). When you get to 32-bit code...

Also not important... "dec cx" sets (or clears) the zero flag, so the "cmp cx, 0" doesn't do anything... doesn't hurt...

Maybe I'm missing "what's wrong?"... The only thing I get from your post is the fact that DEBUG isn't showing the instruction after "mov ss, ax", which is "normal". I really think "segment stack stack" (and *don't* load ss:sp yourself) is "better", but I think it should work the way you've got it. If I need a better definition of "wrong", feel free. :)

Best,
Frank