NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: sploit on April 20, 2010, 12:34:25 PM
-
Been trying different variations of syntax that I've seen and found that using .DATA vs .data I have unexpected results (for me).
take the following
; cmovtest.asm
bits 32
[SECTION .DATA]
output: db "The largest value is %d",0Ah,0h
values: dd 8, 7, 6, 5, 4, 3, 2, 1, 0, 15, 20
valueLen: equ $-values
[SECTION .TEXT]
extern printf
extern exit
global main
main:
nop
mov ebx, [values] ; ebx = values[0]
mov edi, 1
again:
mov eax, [values + edi * 4]
cmp eax, ebx
cmova ebx, eax
inc edi
cmp edi, valueLen
jne again
push ebx ; push the actual value
push output ; Push address of output
call printf
add esp, 8
push 0
call exit
when run the output is: "The largest value is -529"
where the following gives the expected result
; cmovtest.asm
bits 32
[SECTION .data]
output: db "The largest value is %d",0Ah,0h
values: dd 8, 7, 6, 5, 4, 3, 2, 1, 0, 15, 20
valueLen: equ $-values
[SECTION .data]
extern printf
extern exit
global main
main:
nop
mov ebx, [values] ; ebx = values[0]
mov edi, 1
again:
mov eax, [values + edi * 4]
cmp eax, ebx
cmova ebx, eax
inc edi
cmp edi, valueLen
jne again
push ebx ; push the actual value
push output ; Push address of output
call printf
add esp, 8
push 0
call exit
"The largest value is 20"
So why does using .data give me the expected value when .DATA does not?
-
Dunno...
http://www.nasm.us/doc/nasmdoc7.html#section-7.9.2
Last sentence in that section: "Please note that section names are case sensitive."
That doesn't really explain why it works with ".data"... since there's a bug in your program!
When you compare edi to valueLen, valueLen is in bytes, but edi is counting "items" in your array of values (values + edi * 4). If you define valueLen as "valueLen: equ ($ - values) / 4", so it, too, is the count of "items" (dwords), I think you'll find that it works with ".DATA", too. But I'd still switch to ".data"... and ".text". They're the "known" names.
I'd lose the square brackets, too. The difference between "[section .text]" and "section .text" is that the latter is a "macro" form, and as well as generating "[section .text]" (the "raw" form), it sets the "__SECT__" macro to the section name. This "__SECT__" value is used internally by the "struc" mechanism, and it can give funny results if it isn't set right. Usually not a problem, but the "macro" form (without the brackets) is the "preferred" form.
... a little more testing... "section .DATA" is readonly(!) - try "mov dword [values], 0" with it that way! "section .data" is read/write, as intended. As such, it is probably zero-padded to the end of the page, so 20 is the biggest value you encounter, even though you're overshooting the end of your array. A readonly section wouldn't be zero-filled on loading, so some "garbage" is the largest value - so large it's negative, if treated as signed (which "%d" does - but cmova is unsigned...). That's my story, and I'm stickin' to it! :)
Best,
Frank
-
Thanks for all the useful information, first thing I'll be taking away from this is that $-values means bytes which is not necessarily elements.
Luckily my standard coding practice is the macro form with the lowercase section names, however its still fun to know of this behavior for ".DATA".