gpt4 book ai didi

assembly - 在 assembly 中使用 LODSB 需要什么?

转载 作者:行者123 更新时间:2023-12-02 19:46:32 26 4
gpt4 key购买 nike

使用 LODSB 将相对地址加载到我的代码中的字符串所需的最少步骤是什么?

我有以下测试程序,我正在使用 PXE 启动。我通过两种方式启动它:通过 pxelinux.0 和直接启动。如果我直接启动它,我的程序会打印这两个字符串。如果我通过 pxelinux.0 启动,它只会打印第一个字符串。

为什么?

Answer: The code is fine, the initial address math is wrong. See below.

工作技巧(两者):

  • 将方向标志设置为递增,cld
  • 设置dscs
  • 将字符串的地址(从头开始)放入 si
  • 将起始偏移量添加到 si

非工作技术(仅适用于 pxelinux):

  • 根据 (((cs << 4) + offset) >> 4) 计算新的段地址
  • 设置ds对此。 (A000 或 07C0)

text here to 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

这是编译:

/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

最佳答案

第一个问题:

9020:FE00 ==> 9000:0000 而不是 A000:0000
我正在使用 grldrstart.S 中的一些代码来执行该计算。 grldrstart.S 例程中存在错误。它采用 FE00 偏移量并将其右移 4 位,但它不会保留符号; FE00 是负数。所以代替:

shrw   $4, %bx

应该是

sarw   $4, %bx   // Preserves sign!!

90200 + FE00 = 90200 - 200 = 90000

问题解答:

为了使用 LODSB,您必须:

  • 设置ds正确地(并使用正确的数学)
  • 使用 cld 正确设置方向标志或std用于递增和递减
  • 设置si到源缓冲区的偏移量。
  • 读取的有效地址为 (ds << 4) + si

关于assembly - 在 assembly 中使用 LODSB 需要什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2484647/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com