`move byte ptr`、`move word ptr` mov var+1、mov [var]+1 有什么区别?

扎希德汗

我阅读了一些关于
“ptr 做什么?”的早期帖子
'[ ] 做什么?
但我发现对理解以下问题没有任何帮助?

Title : Program failed to comprehend
.model small
.stack 100h
.data
     Msg db 10,13, 'Zahid. $'   
.code
.startup
     ; Initialising data segment
      mov ax, @data
      mov dx, ax
    ;Before operation displaying message
     mov dx, offset msg
     mov ah,09h
     int 21h

      mov msg , 'A'          ; Writing on memory specified by msg thats OK -> A
      mov msg+1 , 'R'     ; Confusion as writing on memory specified by msg then add 1(not 8bits next address write) -> A
      mov [msg]+2, 'I'     ; confusion: Writing on memory specified by msg then add 2 value to that address write-> I
      mov byte ptr [msg+3] , 'F'      ; Ok with me, writing on byte memory specified by msg+3 -> F 
      mov word ptr [msg + 4], '.'      ; Confused again as writing on word memory specified by msg+4, '.' Will it write ascii on the two bytes-> .
      mov msg[5] , '$'   ; Not confused on this.

   ;Print var
    mov dx, offset msg
    mov ah,09h
    int 21h
 
    ;Exit Code.
    mov ah,04ch
    xor al,al
    int 21h
     
Ends

Output : Zahid. ARIF.

请解释操作,因为我认为它不应该打印“ARIF”??

Ped7g

在汇编中,语法取决于特定的汇编程序。Emu8086 主要遵循 MASM 方言,它在规则上相当宽松,并允许多个不同的选项(具有相同的输出)

如果你习惯了一些高级编程语言,这可能会让人感到困惑,为什么语法不是一成不变的,以及如何在 asm 中忍受这种混乱。

但是对于 asm 程序员来说,这很少是一个问题,因为在汇编中你不会用运算符和不同的值构建一些运行时表达式,来自源的指令通常是 1:1 映射到 CPU 指令之一,具有确切的参数和选项CPU中存在的特定指令。

x86 上MOV指令本身有点混乱,因为它是用于许多不同指令操作码的单个助记符“MOV”,但在您的示例中只使用了两条指令:MOV r/m8,imm8操作码C6用于存储字节值,MOV r/m16,imm16操作码C7用于存储字值。在所有情况下,该r/m部分都是绝对偏移量的内存引用,这是在编译时计算的。

因此,如果msg是内存地址的符号0x1000,那么您问题中的那些行将编译为:

; machine code  | disassembled instruction from machine code

C606001041        mov byte [0x1000],0x41

将字节值0x41( 'A') 存储到地址处的内存中ds:0x1000C6 06MOV [offset16],imm8指令操作码,所述00 10字节是0x1000offset16本身(小端),最后41是的imm8值0x41ds默认情况下,将用于计算完整的物理内存地址,因为在该指令之前没有段覆盖前缀。

C606011052        mov byte [0x1001],0x52
C606021049        mov byte [0x1002],0x49
C606031046        mov byte [0x1003],0x46
C70604102E00      mov word [0x1004],0x2e
C606051024        mov byte [0x1005],0x24

剩余的行是相同的故事,在特定的内存偏移处写入字节值,在内存中逐字节地写入,覆盖每一个。

其他行类似的mov word ptr [msg + 4], '.'目标内存地址的细微差别ds:0x1004,但存储的值是imm16,即word值,等于0x002E'.'),因此使用不同的操作码C7,并且立即数需要两个字节2E 00这将ds:0x1004用 byte2Eds:0x1005byte覆盖地址处的内存00

因此,如果地址处的内存msgds:0x1000在我的示例中)位于开头:

0x1000: 0A 0D 5A 61 68 69 64 2E 20 24  ; "\n\rZahid. $"

每次MOV执行后都会变成这样

0x1000: 41 0D 5A 61 68 69 64 2E 20 24  ; "A\rZahid. $"
0x1000: 41 52 5A 61 68 69 64 2E 20 24  ; "ARZahid. $"
0x1000: 41 52 49 61 68 69 64 2E 20 24  ; "ARIahid. $"
0x1000: 41 52 49 46 68 69 64 2E 20 24  ; "ARIFhid. $"
0x1000: 41 52 49 46 2E 00 64 2E 20 24  ; "ARIF.\0d. $"

这个词确实覆盖了两个字节,'h'(带点)和'i'(带零)。

0x1000: 41 52 49 46 2E 24 64 2E 20 24  ; "ARIF.$d. $"

并且该零被再次覆盖为美元符号(DOSint 21h服务的字符串终止符ah=9)。

通常,宽松的语法不是问题,因为您无法构建自己的指令,汇编程序会猜测现有指令中的哪一个适合,并编译您拥有的任何表达式。x86 上没有任何指令,例如mov [address1] and [address2], value在两个不同的内存位置存储相同的值,或者mov [address]+2将两个值添加到内存值中address(这可能取决于变体中的add [address], 2一个,具体取决于数据大小)。add r/m,imm

所以mov msg+1,...只能是 memory address msg + 1,x86 指令集中没有其他有意义的可能性。并且数据大小bytedblabel 之后使用指令中扣除msg:,这是 MASM 和 emu8086 汇编程序的特长,大多数其他汇编程序不会将任何定义的标签(符号)与其后使用的指令链接,即没有符号的“类型”在常见的汇编程序中。对于那些mov msg+1,'R'可能以语法错误结束的人,但不是因为左侧有问题,而是他们不知道该'R'值应该有多大(多少字节)。

我个人最喜欢的 NASM 会报告另一个错误,因为它需要在内存访问周围加上括号,所以只有在 NASM 中才mov [msg+2],...有效(在 MASM 中允许使用像 "byte ptr" 这样的大小修饰符,但没有 "ptr": mov byte [msg+2],...。但在 MASM 中/emu8086 您使用的所有变体都是具有相同含义的有效语法,产生 16b 偏移的内存引用。

汇编器也不会产生两条指令而不是一条指令(例外情况可能是某些汇编器中的特殊“伪指令”,它们被编译为几条本机指令,但这在 x86 汇编中并不常见)。

一旦你知道了目标 CPU 指令集,哪些指令确实存在,你就可以很容易地从模糊的语法中猜测将产生哪条目标指令。

或者您可以轻松地检查调试器反汇编窗口,因为反汇编器将只使用单一的语法方式来处理特定指令,而不知道源格式的歧义。

 mov word ptr [msg + 4], '.'
   ; Confused again as writing on word memory specified by msg+4,
     '.' Will it write ascii on the two bytes-> .

它将写入两个字节,这就是WORD PTRMASM 中指定的内容。但价值仅为'.' = 0x2E. 但是0x2E即使作为 16 位值也完全有效,只需用零扩展到0x002E,这就是汇编程序为此行使用的值。

将来,如果您不确定特定事物的组装方式以及它对 CPU/内存状态的影响,请使用 emu8086 调试器。如果你在这种情况下愿意,你会在反汇编窗口中看到所有这些变体都msg+x编译为内存地址,逐字节覆盖原始msg内存。此外,如果您在msg地址处打开一些内存视图(我希望 emu8086 有一个,我不使用它),您可以观察每次写入内存,它如何更改原始值以及它是如何WORD PTR工作的,因为您没有当然。在调试器中观看通常比在堆栈溢出时阅读这些长答案要容易得多......

关于 PTR 的作用:在汇编中,`PTR` 代表什么?... 不好解释,因为很难解释清楚,整个“BYTE PTR”是 MASM 使用的术语,它不是将其解析为 BYTE 然后对 BYTE 执行某些 PTR 操作,但它会解析它作为“BYTE PTR”,就像“好吧,他想寻址字节”。这就像单个关键字,但有空格。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

MOV BYTE PTR指令如何工作?

来自分类Dev

$ {var:-word}和$ {var-word}有什么区别?

来自分类Dev

“ var = $ {var:-word}”和“ var = $ {var:= word}”之间有什么区别?

来自分类Dev

在聚合物1.x中绑定到[[var]]和{{var}}有什么区别?

来自分类Dev

mov eax,dword ptr [eax]有什么作用?

来自分类Dev

警报var ++和var + 1之间的区别

来自分类Dev

“ $ var”和$ {var}有什么区别?

来自分类Dev

javascript foreach var weird ptr

来自分类Dev

* ptr和** ptr有什么区别?

来自分类Dev

mov(%edx,%ebx,1),%al有什么作用?

来自分类Dev

为什么在做一会儿时用“ mov $ 1,%edx”代替“ mov $ 0,%edx”

来自分类Dev

$var = $var - 1 PHP 问题

来自分类Dev

汇编正确使用word / byte / word ptr

来自分类Dev

汇编正确使用word / byte / word ptr

来自分类Dev

Object.var-和Object.var- = 1之间的区别?

来自分类Dev

mov dword ptr [rsp],eax ss:00000000`0011ddc0 = 00000060是什么意思?

来自分类Dev

swift的if if var和if if有什么区别?

来自分类Dev

为什么 'var' % {1: 'variable'} 打印 'var' 而不是像 'var' % (1,) 那样引发异常 TypeError?

来自分类Dev

!! $ var和(bool)$ var有什么区别?

来自分类Dev

$ {var:= default}与$ {var:-default}-有什么区别?

来自分类Dev

Swift中的var和弱var有什么区别

来自分类Dev

$ {var}和$ {var-}有什么区别

来自分类Dev

在PowerShell中“ $($ var)”和(“ $ var”)有什么区别

来自分类Dev

`VAR = ...`和`export VAR = ...`有什么区别?

来自分类Dev

int var []和int var [0]有什么区别

来自分类Dev

$ var [] = array()和$ var = array()有什么区别?

来自分类Dev

$ {var:= default}与$ {var:-default}-有什么区别?

来自分类Dev

echo $var 和 echo "$var" 有什么区别

来自分类Dev

`${var:-value}` 和 `${var:=value}` 有什么区别?

Related 相关文章

  1. 1

    MOV BYTE PTR指令如何工作?

  2. 2

    $ {var:-word}和$ {var-word}有什么区别?

  3. 3

    “ var = $ {var:-word}”和“ var = $ {var:= word}”之间有什么区别?

  4. 4

    在聚合物1.x中绑定到[[var]]和{{var}}有什么区别?

  5. 5

    mov eax,dword ptr [eax]有什么作用?

  6. 6

    警报var ++和var + 1之间的区别

  7. 7

    “ $ var”和$ {var}有什么区别?

  8. 8

    javascript foreach var weird ptr

  9. 9

    * ptr和** ptr有什么区别?

  10. 10

    mov(%edx,%ebx,1),%al有什么作用?

  11. 11

    为什么在做一会儿时用“ mov $ 1,%edx”代替“ mov $ 0,%edx”

  12. 12

    $var = $var - 1 PHP 问题

  13. 13

    汇编正确使用word / byte / word ptr

  14. 14

    汇编正确使用word / byte / word ptr

  15. 15

    Object.var-和Object.var- = 1之间的区别?

  16. 16

    mov dword ptr [rsp],eax ss:00000000`0011ddc0 = 00000060是什么意思?

  17. 17

    swift的if if var和if if有什么区别?

  18. 18

    为什么 'var' % {1: 'variable'} 打印 'var' 而不是像 'var' % (1,) 那样引发异常 TypeError?

  19. 19

    !! $ var和(bool)$ var有什么区别?

  20. 20

    $ {var:= default}与$ {var:-default}-有什么区别?

  21. 21

    Swift中的var和弱var有什么区别

  22. 22

    $ {var}和$ {var-}有什么区别

  23. 23

    在PowerShell中“ $($ var)”和(“ $ var”)有什么区别

  24. 24

    `VAR = ...`和`export VAR = ...`有什么区别?

  25. 25

    int var []和int var [0]有什么区别

  26. 26

    $ var [] = array()和$ var = array()有什么区别?

  27. 27

    $ {var:= default}与$ {var:-default}-有什么区别?

  28. 28

    echo $var 和 echo "$var" 有什么区别

  29. 29

    `${var:-value}` 和 `${var:=value}` 有什么区别?

热门标签

归档