Was ist erforderlich, um LODSB in der Montage?

Was ist die minimale Menge von Schritten erforderlich, um LODSB laden eine relative Adresse auf einen string in meinem code?

Ich habe Folgendes test-Programm, dass ich per PXE zu Booten. Ich boot es zwei Möglichkeiten: via pxelinux.0 und direkt. Wenn ich das Booten direkt, mein Programm druckt sowohl strings. Wenn ich boot via pxelinux.0, es druckt nur die erste Zeichenfolge.

Warum?

Antwort: Der code ist in Ordnung, die erste Adresse ist die Mathematik falsch. Siehe unten.

Arbeitstechnik (für beide):

  • Die Richtung fahne zu erhöhen, cld
  • Set ds zu cs
  • Setzen Sie die Adresse (vom Anfang) von string in si
  • Fügen Sie den Start-offset zu si

Nicht-Arbeit-Technik (nur für pxelinux):

  • Berechnen Sie ein neues segment-Adresse, basierend auf (((cs << 4) + offset) >> 4)
  • Set ds zu. (entweder A000 oder 07C0)

text hier zu fix bug in markdown

//Note: If you try this code, don't forget to set 
//      the "#if 0" below appropriately!

    .text
    .globl  start, _start

start:  
_start: 
_start1:    

    .code16

    jmp real_start

    . = _start1 + 0x1fe
    .byte 0x55, 0xAA

    //Next sector
    . = _start1 + 0x200

    jmp real_start

test1_str:
    .asciz  "\r\nTest: 9020:fe00"
test2_str:
    .asciz  "\r\nTest: a000:0000"

real_start:

    cld         //Make sure %si gets incremented.

#if 0
    //When loaded by pxelinux, we're here:
    //9020:fe00 ==> a000:0000

    //This works.
    movw    $0x9020, %bx
    movw    %bx, %ds
    movw    $(test1_str - _start1), %si
    addw    $0xfe00, %si
    call    print_message

    //This does not.
    movw    $0xA000, %bx
    movw    %bx, %ds
    movw    $(test2_str - _start1), %si
    call    print_message
#else
    //If we are loaded directly without pxelinux, we're here:
    //0000:7c00 ==> 07c0:0000

    //This works.
    movw    $0x0000, %bx
    movw    %bx, %ds
    movw    $(test1_str - _start1), %si
    addw    $0x7c00, %si
    call    print_message

    //This does, too.
    movw    $0x07c0, %bx
    movw    %bx, %ds
    movw    $(test2_str - _start1), %si
    call    print_message
#endif

    //Hang the computer
    sti
1:
    jmp 1b


//Prints string DS:SI (modifies AX BX SI)
print_message:
    pushw   %ax
    jmp 2f
3:
    movb    $0x0e, %ah  /* print char in AL */
    int $0x10       /* via TTY mode */
2:  
    lodsb   (%si), %al  /* get token */
    cmpb    $0, %al     /* end of string? */
    jne 3b
    popw    %ax
    ret

.balign 0x200

Hier ist die Zusammenstellung:

/usr/bin/ccache gcc -Os -fno-stack-protector -fno-builtin -nostdinc  -DSUPPORT_SERIAL=1 -DSUPPORT_HERCULES=1 -DSUPPORT_GRAPHICS=1 -DHAVE_CONFIG_H -I. -Wall -ggdb3 -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef -g -c -o ds_teststart_exec-ds_teststart.o ds_test.S
/usr/bin/ccache gcc  -g   -o ds_teststart.exec -nostdlib -Wl,-N -Wl,-Ttext -Wl,8000 ds_teststart_exec-ds_teststart.o  
objcopy -O binary ds_teststart.exec ds_teststart
  • Wenn das problem sich herausstellt, etwas ganz anderes geht, werd ich wieder Wort die ganze Frage für die Antwort.
InformationsquelleAutor Harvey | 2010-03-20
Schreibe einen Kommentar