NASM - The Netwide Assembler
NASM Forum => Example Code => Topic started by: nobody 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:
[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
-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 :
mov ax, stack
mov ss, ax
mov sp, 100
mov ax, data
what's wrong ??
welcome to talk to me.
-
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:
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:
segment stack stack
resb 100
With this small change, dos will load your program with ss:sp properly set, and the:
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