Recent Posts

Pages: [1] 2 3 ... 10
1
Programming with NASM / Re: If/Elseif/Else statement with macros
« Last post by MIchael on May 24, 2018, 10:11:50 PM »
Hi to all! After a long search on the Internet I couldn't solve my problem. How to implement If/Elseif/Else statement with macros, just like this:
Code: [Select]
if al, equal, bl
    mov rcx, 128
elseif al, greater, bl
    mov rcx, 1
else
    mov rcx, 0
endif
Just like this?

%define equal ne
%define n_equal e
; you can add more definitions there

%macro if 3
    %push if
    cmp %1, %3
    j%2 %$ifnot
%endmacro

%macro elseif 3
    %ifctx if
%$ifnot:
        cmp %1, %3
        j%2 %$ifnot
    %else
       %error "ELSIF directive must be within an 'if' block."
    %endif
%endmacro
   
%macro else 0
    %ifctx if
        %repl else
        jmp %$ifend
%$ifnot:
    %else
        %error "ELSE directive must be within an 'if' or 'elseif' block."
    %endif
%endmacro
   
%macro endif 0
    %ifctx if
%$ifnot:
        %pop
    %elifctx else
%$ifend:
        %pop
    %else
        %error "ENDIF directive must be within an 'if' block."
    %endif
%endmacro
2
Programming with NASM / Re: If/Elseif/Else statement with macros
« Last post by avcaballero on May 24, 2018, 07:02:59 PM »
Maybe you may have a look to the nasmx package. The win32\Demo15 use it:
Code: [Select]
if eax,ABOVE,[argv(.h)]
fdivp st1,st0  ; w/h
fld st0
fmul qword [var(.right)]
fxch
fmul qword [var(.left)]
fstp qword [var(.left)]
fstp qword [var(.right)]
else
fdivrp st1,st0 ; h/w
fld st0
fmul qword [var(.top)]
fxch
fmul qword [var(.bottom)]
fstp qword [var(.bottom)]
fstp qword [var(.top)]
endif
3
Programming with NASM / Making If/Elseif/Else statement with macros
« Last post by MIchael on May 24, 2018, 12:11:01 PM »
Hi to all! After a long search on the Internet I couldn't solve my problem. How to implement If/Elseif/Else statement with macros, just like this:
Code: [Select]
if al, equal, bl
    mov rcx, 128
elseif al, greater, bl
    mov rcx, 1
else
    mov rcx, 0
endif
4
Using NASM / Re: Translating a c program to nasm win32
« Last post by dreamCoder on May 22, 2018, 01:00:59 AM »
This is NOT what is asked for. It might be some help...

Best,
Frank


Code: [Select]
;-----------------------------------------------
; converts centigrade to fahrenheit, & visa versa
;
; nasm -f bin -o myfile.com myfile.asm
;--------------------------------------

org 100h

BUFSIZ equ 8

section .data

    prompt0 db 13, 10, 7, 'Pay Attention!!!', 13, 10, '$'
    prompt1 db 13, 10, 'This humble program will convert', 13, 10
            db 'degrees centigrade to degrees Fahrenheit,', 13, 10
            db 'or Fahrenheit to centigrade (Celsius).', 13, 10
            db 'Please enter "C" or "F" to indicate the', 13, 10
            db 'temperature units in which you will INPUT', 13, 10
            db 'the value to be converted.', 13, 10, 10  , '$'
    promptc db 'Please enter degrees C to convert to F:', 13, 10, '$'
    promptf db 'Please enter degrees F to convert to C:', 13, 10, '$'
    that    db 13, 10, "That's $"
    degrees db ' degrees $'
    bye     db 13, 10, 10, "Thanks for playing!", 13, 10, '$'


    word_10 dw 10   ; multiplier for the float-to-ascii routine

                    ; for C->F, F->C routines
    float_32 dq 32.0
    float_5  dq 5.0
    float_9  dq 9.0

section .bss

    buffer resb BUFSIZ + 2     ; buffer for our input string
    result_units resb 1        ; holds 'C' or 'F'
    numbuf resb 20h            ; buffer for ftoa
    bcdbuf rest 1              ; 10 byte scratch area for ftoa
;--------------------

section .text

; cheap-a** cls - reset text mode
    mov ax, 3
    int 10h

instruct:
; tell 'em what we're gonna do, and ask for input
    mov dx, prompt1
    mov ah, 9
    int 21h

; get input - one key, no echo
    mov ah, 8
    int 21h

; force uppercase
    and al, 0DFh

; did they get it right?
    cmp al, 'C'
    je do_c2f

    cmp al, 'F'
    je do_f2c

; smack their a**, and make 'em do it over
    mov dx, prompt0
    mov ah, 9
    int 21h
    jmp short instruct

; store the letter we'll display at the end
; we also use it as a "flag" to decide f->c or c->f
; and set up appropriate prompt
do_c2f:
    mov byte [result_units], 'F'
    mov dx, promptc
    jmp short both
do_f2c:
    mov byte [result_units], 'C'
    mov dx, promptf

both:
; display the prompt, "C" or "F", asking for input
    mov ah, 9
    int 21h

; get string input, set "max size" first
    mov byte [buffer], BUFSIZ
    mov ax, 0C0Ah
    mov dx, buffer
    int 21h

; since atof expects a zero-terminated string, do so.
    mov bl, [buffer + 1]
    xor bh, bh
    mov byte [buffer + 2 + bx], 0

; convert the string to a float in st(0)
; remember that input text starts at 2 bytes into the buffer
    mov si, buffer + 2
    call atof
    jnc good_num

; if they gave us trash, give 'em trash back
; and make 'em do it over
    mov dx, prompt0
    int 21h
    mov dx, promptc
    cmp byte [result_units], 'F'
    je both
    mov dx, promptf
    jmp short both

good_num:
; okay, they did right, do the calculation they want
    cmp byte [result_units], 'C'
    jne calc_c2f

    fsub qword [float_32]
    fmul qword [float_5]
    fdiv qword [float_9]
    jmp short display

calc_c2f:
    fmul qword [float_9]
    fdiv qword [float_5]
    fadd qword [float_32]
; Whew! That was tough!

display:
; convert st(0) to ascii string at di - cx decimal places
    mov cx, 2
    mov di, numbuf
    call ftoa

; ftoa returns a zero-terminated string,
; fix it for int 21h/9 - '$'-terminate
    dec di
reterminate:
    cmp byte [di + 1], 1
    inc di
    jnc reterminate
    mov byte [di], '$'

; tell 'em what we're going to do
    mov ah, 9
    mov dx, that
    int 21h

 ; tell 'em the number
    mov dx, numbuf
    int 21h

; and the units
    mov dx, degrees
    int 21h

    mov ah, 2
    mov dl, [result_units]
    int 21h

; say Buhbye - enhancement - go again?
    mov ah, 9
    mov dx, bye
    int 21h

exit:
    mov ah,4Ch
    int 21h

;------------------------------------------------
; atof - converts ascii string to float
; expects: si pointed to zero-terminated string
; returns: float in st(0)
;          carry set if invalid digit encountered
;-------------------------------------------------
atof:
    push ax
    push bx
    push cx
    push dx
    push di
    push si

    xor bx, bx

    xor cx, cx
    dec cx                    ; set cx FFFF - no point found

    xor dx, dx
    mov byte [bcdbuf + 9], 0  ; assume positive

    mov di, si                ; save our "beginning of buffer"

.af0:
    mov al, [si]
    inc si
    cmp al, '-'
    jnz .notneg
    mov byte [bcdbuf + 9], 80h
    jmp short .af0
.notneg:
    cmp al, '.'
    jnz .notpt
    inc cx
    jmp short .af0
.notpt:
    cmp al, ' '
    jz .af0
    cmp cx, 0FFFFh
    jz .af05
    inc cx
.af05
    or al, al        ; end of string?
    jnz .af0
    dec si
    dec si
    cmp cx, 0FFFFh
    jnz .af07
    xor cx, cx
    jmp short .af1
.af07
    dec cx

.af1:
    cmp si, di
    jc .done
    mov al, [si]
    dec si
    cmp al, ' '
    jz .af1
    cmp al, '-'
    jz .af1
    cmp al, '.'
    jz .af1
    cmp al, 3Ah
    jnc .invalid
    cmp al, 30h
    jc .invalid
    and al, 0Fh
    or dh, dh
    jnz .notfirst
    or dl, al
    inc dh
    jmp short .af1
.notfirst:
    shl al, 4
    or dl, al
    mov [bcdbuf + bx], dl
    xor dx, dx
    inc bx
    jmp .af1
.invalid
    stc
    jmp short .done3

.done
    or dh, dh
    jz .padbcd
    and dl, 0Fh
    mov [bcdbuf + bx], dl
    inc bx

.padbcd
    cmp bx, byte 9
    jz .done2
    mov byte [bcdbuf + bx], 0
    inc bx
    jmp short .padbcd

.done2
    fbld [bcdbuf]
    or cx, cx
    jz .done25
.tendiv:
    fidiv word [word_10]
    loop .tendiv
.done25
    clc
.done3:

    pop si
    pop di
    pop dx
    pop cx
    pop bx
    pop ax
    ret
;--------------------------------------------


;-----------------------------------------------------
; ftoa - converts floating point to string
;
; Based on some code "sponged" from a post to clax
; From: "Jim Morrison" <astrolabe at ntplx dot net>
;
; Expects: Number to convert is on stack top - st(0)
;          di points to buffer to store string
;          cx = Decimal Places.
;-------------------------------------------------------------

ftoa:
    push ax
    push cx
    push dx
    push di
    push si

    mov dx, cx           ; save a copy of dec places
                         ; if no decimal (integer)
    jcxz .f2a2           ; skip multiply by ten loop
.f2a1:                   ; else loop to "scale" number
    fimul word [word_10]
    loop .f2a1
.f2a2:
    fbstp [bcdbuf]       ; convert to bcd and store
    mov si, bcdbuf       ; we'll pull digits from there
    mov cx, 9
.f2a3:
    lodsb                ; get a pair of digits
    mov ah, al           ; move a copy to ah
    shr ah, 4            ; shift out low nibble, keeping high
    and ax, 0F0Fh        ; mask out the digits we want
    add ax, 3030h        ; convert 'em both to ascii
    push ax
    mov al, ah           ; swap and store the other digit
    push ax
    loop .f2a3           ; until done

    cmp byte [bcdbuf+9], 0 ; sign flag at bcdbuf + 9 ?
    je .f2a6
    mov al, '-'           ; minus sign if we need it
    stosb                 ; store it at front of our string
.f2a6:

    mov cx, 18
    xor dh, dh
    inc dl
.poploop
    pop ax
    cmp al, '0'
    jnz .store
    or dh, dh
    jnz .store
    jmp short .nostore
.store
    stosb
    inc dh
.nostore
    cmp cl, dl
    jne .nopoint
    or dh, dh       ; if we haven't encountered a non-zero
    jnz .nolz
    mov al, '0'     ; put a zero before the decimal point
    stosb
.nolz
    mov al, '.'           ; decimal point
    stosb                 ; and store it
    inc dh
.nopoint
    loop .poploop

    mov al, 0
    stosb

    pop si
    pop di
    pop dx
    pop cx
    pop ax

    ret
;--------------------------------------------------

HAHAHA :D
5
After "investigating" what "getpwnam" looks like in assembly, here's the summary of the data structure (64-bit Linux);

1. Total size 48 bytes.
2. 7 data members
3. "uidt_xx" and "gidt_xx" are dwords each.
4. All other data members / fields are quadwords pointers
5. There's an undefined data returned (0x400) at the end of the structure. So it is safe to assume that the total size of the structure is 56 bytes. This is in contrast to what's being defined by the "getpwnam(3)" Man which listed only 7 data members. There's actually 8 data members :D

Hope this can shed some lights.

 

 
6
Using NASM / Re: Translating a c program to nasm win32
« Last post by Frank Kotler on May 22, 2018, 12:47:42 AM »
This is NOT what is asked for. It might be some help...

Best,
Frank


Code: [Select]
;-----------------------------------------------
; converts centigrade to fahrenheit, & visa versa
;
; nasm -f bin -o myfile.com myfile.asm
;--------------------------------------

org 100h

BUFSIZ equ 8

section .data

    prompt0 db 13, 10, 7, 'Pay Attention!!!', 13, 10, '$'
    prompt1 db 13, 10, 'This humble program will convert', 13, 10
            db 'degrees centigrade to degrees Fahrenheit,', 13, 10
            db 'or Fahrenheit to centigrade (Celsius).', 13, 10
            db 'Please enter "C" or "F" to indicate the', 13, 10
            db 'temperature units in which you will INPUT', 13, 10
            db 'the value to be converted.', 13, 10, 10  , '$'
    promptc db 'Please enter degrees C to convert to F:', 13, 10, '$'
    promptf db 'Please enter degrees F to convert to C:', 13, 10, '$'
    that    db 13, 10, "That's $"
    degrees db ' degrees $'
    bye     db 13, 10, 10, "Thanks for playing!", 13, 10, '$'


    word_10 dw 10   ; multiplier for the float-to-ascii routine

                    ; for C->F, F->C routines
    float_32 dq 32.0
    float_5  dq 5.0
    float_9  dq 9.0

section .bss

    buffer resb BUFSIZ + 2     ; buffer for our input string
    result_units resb 1        ; holds 'C' or 'F'
    numbuf resb 20h            ; buffer for ftoa
    bcdbuf rest 1              ; 10 byte scratch area for ftoa
;--------------------

section .text

; cheap-a** cls - reset text mode
    mov ax, 3
    int 10h

instruct:
; tell 'em what we're gonna do, and ask for input
    mov dx, prompt1
    mov ah, 9
    int 21h

; get input - one key, no echo
    mov ah, 8
    int 21h

; force uppercase
    and al, 0DFh

; did they get it right?
    cmp al, 'C'
    je do_c2f

    cmp al, 'F'
    je do_f2c

; smack their a**, and make 'em do it over
    mov dx, prompt0
    mov ah, 9
    int 21h
    jmp short instruct

; store the letter we'll display at the end
; we also use it as a "flag" to decide f->c or c->f
; and set up appropriate prompt
do_c2f:
    mov byte [result_units], 'F'
    mov dx, promptc
    jmp short both
do_f2c:
    mov byte [result_units], 'C'
    mov dx, promptf

both:
; display the prompt, "C" or "F", asking for input
    mov ah, 9
    int 21h

; get string input, set "max size" first
    mov byte [buffer], BUFSIZ
    mov ax, 0C0Ah
    mov dx, buffer
    int 21h

; since atof expects a zero-terminated string, do so.
    mov bl, [buffer + 1]
    xor bh, bh
    mov byte [buffer + 2 + bx], 0

; convert the string to a float in st(0)
; remember that input text starts at 2 bytes into the buffer
    mov si, buffer + 2
    call atof
    jnc good_num

; if they gave us trash, give 'em trash back
; and make 'em do it over
    mov dx, prompt0
    int 21h
    mov dx, promptc
    cmp byte [result_units], 'F'
    je both
    mov dx, promptf
    jmp short both

good_num:
; okay, they did right, do the calculation they want
    cmp byte [result_units], 'C'
    jne calc_c2f

    fsub qword [float_32]
    fmul qword [float_5]
    fdiv qword [float_9]
    jmp short display

calc_c2f:
    fmul qword [float_9]
    fdiv qword [float_5]
    fadd qword [float_32]
; Whew! That was tough!

display:
; convert st(0) to ascii string at di - cx decimal places
    mov cx, 2
    mov di, numbuf
    call ftoa

; ftoa returns a zero-terminated string,
; fix it for int 21h/9 - '$'-terminate
    dec di
reterminate:
    cmp byte [di + 1], 1
    inc di
    jnc reterminate
    mov byte [di], '$'

; tell 'em what we're going to do
    mov ah, 9
    mov dx, that
    int 21h

 ; tell 'em the number
    mov dx, numbuf
    int 21h

; and the units
    mov dx, degrees
    int 21h

    mov ah, 2
    mov dl, [result_units]
    int 21h

; say Buhbye - enhancement - go again?
    mov ah, 9
    mov dx, bye
    int 21h

exit:
    mov ah,4Ch
    int 21h

;------------------------------------------------
; atof - converts ascii string to float
; expects: si pointed to zero-terminated string
; returns: float in st(0)
;          carry set if invalid digit encountered
;-------------------------------------------------
atof:
    push ax
    push bx
    push cx
    push dx
    push di
    push si

    xor bx, bx

    xor cx, cx
    dec cx                    ; set cx FFFF - no point found

    xor dx, dx
    mov byte [bcdbuf + 9], 0  ; assume positive

    mov di, si                ; save our "beginning of buffer"

.af0:
    mov al, [si]
    inc si
    cmp al, '-'
    jnz .notneg
    mov byte [bcdbuf + 9], 80h
    jmp short .af0
.notneg:
    cmp al, '.'
    jnz .notpt
    inc cx
    jmp short .af0
.notpt:
    cmp al, ' '
    jz .af0
    cmp cx, 0FFFFh
    jz .af05
    inc cx
.af05
    or al, al        ; end of string?
    jnz .af0
    dec si
    dec si
    cmp cx, 0FFFFh
    jnz .af07
    xor cx, cx
    jmp short .af1
.af07
    dec cx

.af1:
    cmp si, di
    jc .done
    mov al, [si]
    dec si
    cmp al, ' '
    jz .af1
    cmp al, '-'
    jz .af1
    cmp al, '.'
    jz .af1
    cmp al, 3Ah
    jnc .invalid
    cmp al, 30h
    jc .invalid
    and al, 0Fh
    or dh, dh
    jnz .notfirst
    or dl, al
    inc dh
    jmp short .af1
.notfirst:
    shl al, 4
    or dl, al
    mov [bcdbuf + bx], dl
    xor dx, dx
    inc bx
    jmp .af1
.invalid
    stc
    jmp short .done3

.done
    or dh, dh
    jz .padbcd
    and dl, 0Fh
    mov [bcdbuf + bx], dl
    inc bx

.padbcd
    cmp bx, byte 9
    jz .done2
    mov byte [bcdbuf + bx], 0
    inc bx
    jmp short .padbcd

.done2
    fbld [bcdbuf]
    or cx, cx
    jz .done25
.tendiv:
    fidiv word [word_10]
    loop .tendiv
.done25
    clc
.done3:

    pop si
    pop di
    pop dx
    pop cx
    pop bx
    pop ax
    ret
;--------------------------------------------


;-----------------------------------------------------
; ftoa - converts floating point to string
;
; Based on some code "sponged" from a post to clax
; From: "Jim Morrison" <astrolabe at ntplx dot net>
;
; Expects: Number to convert is on stack top - st(0)
;          di points to buffer to store string
;          cx = Decimal Places.
;-------------------------------------------------------------

ftoa:
    push ax
    push cx
    push dx
    push di
    push si

    mov dx, cx           ; save a copy of dec places
                         ; if no decimal (integer)
    jcxz .f2a2           ; skip multiply by ten loop
.f2a1:                   ; else loop to "scale" number
    fimul word [word_10]
    loop .f2a1
.f2a2:
    fbstp [bcdbuf]       ; convert to bcd and store
    mov si, bcdbuf       ; we'll pull digits from there
    mov cx, 9
.f2a3:
    lodsb                ; get a pair of digits
    mov ah, al           ; move a copy to ah
    shr ah, 4            ; shift out low nibble, keeping high
    and ax, 0F0Fh        ; mask out the digits we want
    add ax, 3030h        ; convert 'em both to ascii
    push ax
    mov al, ah           ; swap and store the other digit
    push ax
    loop .f2a3           ; until done

    cmp byte [bcdbuf+9], 0 ; sign flag at bcdbuf + 9 ?
    je .f2a6
    mov al, '-'           ; minus sign if we need it
    stosb                 ; store it at front of our string
.f2a6:

    mov cx, 18
    xor dh, dh
    inc dl
.poploop
    pop ax
    cmp al, '0'
    jnz .store
    or dh, dh
    jnz .store
    jmp short .nostore
.store
    stosb
    inc dh
.nostore
    cmp cl, dl
    jne .nopoint
    or dh, dh       ; if we haven't encountered a non-zero
    jnz .nolz
    mov al, '0'     ; put a zero before the decimal point
    stosb
.nolz
    mov al, '.'           ; decimal point
    stosb                 ; and store it
    inc dh
.nopoint
    loop .poploop

    mov al, 0
    stosb

    pop si
    pop di
    pop dx
    pop cx
    pop ax

    ret
;--------------------------------------------------
7
Using NASM / Re: Translating a c program to nasm win32
« Last post by dreamCoder on May 21, 2018, 11:40:04 PM »
No this doesn't look like homework. Sorry.

This looks like more of "we-make-assignments" balonies trying to get some free answers on behalf of their customers. No wonder why nobody comes back for "discussions" after registering and posting a question / getting the answers. :D
8
There's no easy way to do that in Linux assembly. Assembly language in Linux is largely uncharted. You must see everything from C's point of view.

The problem lies in how the kernel services are documented --> it uses C as the main API interface language to describe the kernel binaries (assembly code). They're actually not the C library. They are kernel services/binaries "described" in C language. Two different things here. So one needs to guess each of the data fields, and to make things worse, different distros / kernels / toolchain may use different sizes for the same data field.

However, the total size of a structure can be manually determined by placing some visual markers among the data returned by the kernel. Thats the best approximation you can get if you want to know the size of a kernel's data structure. Here's what I always do if it has to come down to that point;

1. Assign large enough buffer for the structure in question
2. Place some markers (e,g -1 or 0xffffffffffffffff) at the end portion of the buffer
3. Call the kernel. The kernel will then return the data in that buffer.
4. Shrink the size of the buffer until the marker is gone or eaten up.
5. The net difference of data from that marker is the total size of the structure returned by the kernel.
6. Identifying individual data fields from the returned structure is close to impossible. You need to apply some hunch and educated guess. 

Btw, from your first code, I'd say that they have nothing to do with the data structure. With lots of RBP addressings, I say they are local variables on the stack frame, internal to that particular syscall. Logically, the data structure is most likely to be placed in static memory area or heap, and not on the stack. The only thing passed to the stack is probably the pointer to the data structure.

Don't take my words for it. Just sharing my experience dealing with such problems in Linux assembly.

9
Thanks a lot,
so now, how do you determine what is a "library function" and a "system call?" A syscall should be followed by a "syscall" in x64, correct? A lot of these syscalls have the same name as C lib functions, but when you are looking at disassembly, how to differentiate them? Should I be reviewing manpages for the library functions or for the syscalls?
10
Anyway, thanks for helping!
Pages: [1] 2 3 ... 10